Announcement Announcement Module
Collapse
No announcement yet.
Assistance request for autoproxying with prototype scoped beans Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Assistance request for autoproxying with prototype scoped beans

    I'm looking for advice/assistance in setting up transactional autoproxying for a number of similar prototype scoped beans. The beans in question are service beans, that are used in a JSF web application. The service beans are created/invoked from request scoped JSF managed beans, and because the only reference to the services are in the managed beans, the service beans are effectively request scoped as well. The service beans contain state for the scope of the request, and have to maintain that over mutiple method calls from the managed bean, so they cannot be instanced as singletons.

    Originally, transactional proxying was done “brute force” by proxying each bean using TransactionProxyFactoryBean, as in the code example 1 below.

    This worked fine, but required a lot of duplicate configuration and entries (there are 100's of these service beans). I've tried to simply this by using abstract beans, and BeanNameAutoProxyCreator, as shown in example 2 below. However, I have found that as a result, effectively my service beans have become singletons. As best as I can tell, BeanNameAutoProxyCreator is always creating a singleton proxy, which wraps my prototype service. But since the proxy is a singleton, it effectively turns my prototype service into a singleton as well.

    I’ve done some web research, and looked over the forums, and I haven’t found a way to make BeanNameAutoProxyCreator return a prototype proxy.

    In the course of my research, I also noticed that TransactionProxyFactoryBean it is documented as being designed to be used for “wrapping a singleton target object with a transactional proxy”. It seems to work fine with prototypes, but it doesn't help with autoproxying.

    I’ve also looked at using ProxyFactoryBean with a PrototypeTargetSource, but every solution I can devise here seems to lose the autoproxying, and has me back to defining proxys on a service by service basis

    Any guidance/suggestions on how to combine autoproxying with prototype beans would be appreciated.

    Code example 1 – original configuration
    Code:
    	<bean id="ServiceHomeTarget"
    		class="com.myobjects.ServiceHomeImpl"
    		scope="prototype">
    		<property name="companyDao" ref="CompanyDao" />
    		<property name="messageFactory" ref="MessageFactory" />
    	</bean>
    
    	<bean id="ServiceHome"
    	class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="TxManager" />
    		<property name="target" ref="ServiceHomeTarget" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRES_NEW</prop>
    			</props>
    		</property>
    	</bean>
    Code example 2 – Auto proxy example - NOT WORKING (getting singleton scoped proxies)
    Code:
    <bean id="transactionAttributes" 
    	class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
        <property name="properties">
            <value>
                *=PROPAGATION_REQUIRED
            </value>
        </property>
    </bean>
    
    <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    	<property name="transactionManager">
    		<ref bean="TxManager"/>
    	</property>
    	<property name="transactionAttributeSource">
    		<ref bean="transactionAttributes"/>
    	</property>
    </bean>
    
    <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    	<property name="interceptorNames">
            <value>transactionInterceptor</value>
    	</property>
    	<property name="beanNames">
           <list>
              <value>Service*</value>
           </list>
    	</property>
    </bean>
    
    	<bean id="abstractService" abstract="true" scope="prototype">
    		<property name="messageFactory" ref="MessageFactory" />
    	</bean>
    
    	<bean class=" com.myobjects.ServiceHomeImpl" id="ServiceHome" parent="abstractService" >
    		<property name="companyDao" ref="CompanyDao" />
    </bean>

  • #2
    As the saying goes "Never Mind".

    More testing proved my assumption about BeanNameAutoProxyCreator incorrect. The error is in my abstractSerivce bean definition. Because I'm not specifying a scope in my ServiceHome bean, its coming through as a singleton, which overrides the scope=prototype in the abstractService definition. With that corrected, the BeanNameAutoProxyCreator is creating prototype proxies.

    So all that seems to be needed for my setup to work is to add scope=prototype to each of my individual bean definitions, rather than assuming this would be provided by the parent.

    Comment

    Working...
    X