Search This Blog

Wednesday, 9 January 2013

FactoryBean Interface in Spring

In our post on Velocity integration in Spring we saw an example of a FactoryBean. If we look at the configuration for velocity:
<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