In our post on Velocity integration in Spring we saw an example of a FactoryBean. If we look at the configuration for velocity:
So how does this work? I scoured the net and came across this excellent piece on FactoryBean.
From the site:
This concept of FactoryBean is heavily used in Spring. Similar is the case when working with Hibernate:
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> //...However in our java class:
public class TemplateTester { private VelocityEngine velocityEngine; //...As seen the declared dependency and the reference in the code are different. I though that the class VelocityEngineFactoryBean might be extending VelocityEngine. However a look inside the source code indicated differently.
public class VelocityEngineFactoryBean extends VelocityEngineFactory implements FactoryBean<VelocityEngine>, InitializingBean, ResourceLoaderAware { private VelocityEngine velocityEngine; //...As seen the class includes a reference to VelocityEngine, but does not in any manner extend the hierarchy.
So how does this work? I scoured the net and came across this excellent piece on FactoryBean.
From the site:
A FactoryBean is a pattern to encapsulate interesting object construction
logic in a class.It might be used, for example, to encode the
construction of a complex object graph in a reusable way. Often this is
used to construct complex objects that have many dependencies.
It might also be used when the construction logic itself
is highly volatile and depends on the configuration. A FactoryBean is
also useful to help Spring construct objects that it couldn't easily construct itself.
In case of velocity, there is quite a lot of code that goes in initializing the Velocity Engine and configuring it. All this complex code which varies based on
scenarios, has been written and placed in the VelocityEngineFactory's createVelocityEngine() method.
When Spring comes across a FactoryBean dependency it
does not wire the FactoryBean as a dependency. Instead it wires the instance returned by getObject() as the dependency.
In case of VelocityEngineFactoryBean the code is:private VelocityEngine velocityEngine; public void afterPropertiesSet() throws IOException, VelocityException { this.velocityEngine = createVelocityEngine(); } public VelocityEngine getObject() { return this.velocityEngine; }As can be seen when the VelocityEngineFactoryBean was created, it went on to create an instance of VelocityEngine. It is this instance that it returns as a part of the getObject() method.
This concept of FactoryBean is heavily used in Spring. Similar is the case when working with Hibernate:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> //more configuration...This class is a subclass of FactoryBean (through a long hierarchy). If we look inside it (up the hierarchy):
public abstract class AbstractSessionFactoryBean extends HibernateExceptionTranslator implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean { /** * * Return the singleton SessionFactory. */ public SessionFactory getObject() { return this.sessionFactory; } public Class<? extends SessionFactory> getObjectType() { return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); } // other methods... }This concept of wrapping the complexities of objects behind factory beans has been used heavily in Spring jars. I found it in diverse technology integration modules ranging from EJB to EhCache to HTTPInvoker to JAXRC to even something as commonly used as Quartz. Using Eclipse, simply search for references of FactoryBean and you would be overwhelmed by the result.
No comments:
Post a Comment