Sunday, September 23, 2007

Did You Know: Spring Object Pooling

A subject came up recently in the Spring Framework Spring-User mailing list regarding object pooling. The original mis-conception (that was triggered by the wording in the Spring documentation) was that Spring doesn't support object pooling. This isn't neccessarily true depending on the release of Spring that you are using. (Note: When I refer to release, I am not referring to the version, but rather which distribution; e.g.: spring-core, spring-web, spring-mvc, etc.) The core bean factory code of Spring does not support object pooling; instead it supports singleton objects and what they refer to as prototype objects, which simply means that Spring returns a new object everytime you request the bean with that particular id from the bean factory. (Spring Documentation Reference) For example:

    <!-- This will always be the same bean (Singleton is default -->
    <bean id="bean1" /> 

    <!-- This will be a new bean every time you request it -->
    <bean id="bean2" singleton="false"/>
While the documentation is 100% correct in saying that bean factories don't support object pooling (or more specifically saying that they only support singletons and prototypes), there is no mention of the object pooling that is available if you are using a release of Spring that contains Spring AOP support. Spring supports what's called a Target Source. The description in the documentation is somewhat complicated if you aren't familiar with Spring AOP, but long story short, Spring uses a class called ProxyFactoryBean to create an AOP wrapper for a bean. By default, you set the 'target' to the bean you want to wrap with AOP interceptors (target means the bean that is being layered with some advice). However, a target source is an interim factory for a given object type that sits between the ProxyFactoryBean and your target bean. The term 'target source' sounds confusing, but is also self-explanatory. It is a source for the proxy bean to use when retrieving 'target' objects. Here is the XML snippet for Pooling Target Sources directly from the Spring documentation:
    <bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject" 
        singleton="false">
        ... properties omitted
    </bean>

    <bean id="poolTargetSource" 
        class="org.springframework.aop.target.CommonsPoolTargetSource">
        <property name="targetBeanName"><value>businessObjectTarget</value></property>

        <property name="maxSize"><value>25</value></property>
    </bean>

    <bean id="businessObject" 
        class="org.springframework.aop.framework.ProxyFactoryBean"
    >
        <property name="targetSource"><ref local="poolTargetSource"/></property>

        <property name="interceptorNames"><value>myInterceptor</value></property>
    </bean>
By Lorimer

3 comments:

Alan said...

The line:

StrutsSpringObjectFactory.setObjectFactory(ssf);

Does not works in struts 2.1 snapshot.

I trace the code and find out that ObjectFactory in xworks 2.1 drop the singleton pattern. Would you mind giving me any suggestion to do the same things in struts 2.1 (+ xworks 2.1)

ilya said...

the documentation for Spring 2.5 seems to suggest that the way pooling works is that every method invocation on the target gets a different object from the pool. is that the case?

ilya said...

indeed that turns out to be the case. the object is retrieved from the pool each time a method is invoked, and returned to the pool when the method completes.