配置Spring,针对Service层的bean做事务处理

来源:互联网 发布:java ping ip 编辑:程序博客网 时间:2024/06/01 09:46

配置Spring,针对Service层的bean做事务处理,以往的做法是这样:

代码
  1. <bean id="txProxyTemplate" abstract="true"    
  2. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">    
  3.     <property name="transactionManager">  
  4.         <ref bean="transactionManager"/>  
  5.     </property>    
  6.     <property name="transactionAttributes">    
  7.         <props>  
  8.             <prop key="find*">PROPAGATION_REQUIRED, readOnly</prop>    
  9.             <prop key="*">PROPAGATION_REQUIRED</prop>    
  10.         </props>    
  11.     </property>    
  12. </bean>    
  13.   
  14. <bean id="userManager" parent="txProxyTemplate">    
  15.     <property name="target">    
  16.         <bean class="some.package.UserManagerImpl">    
  17.             <property name="userDAO"><ref bean="userDAO"/></property>    
  18.         </bean>    
  19.     </property>    
  20. </bean>    
  21.   

 

以后,如果增加新的Service/Manager,则XML配置的增量是这一段:

代码
  1. <bean id="someOtherManager" parent="txProxyTemplate">    
  2.     <property name="target">    
  3.         <bean class="some.package.someOtherManagerImpl">    
  4.         </bean>    
  5.     </property>    
  6. </bean>    

 

上面说的是老的做法,比较传统。缺点是增量比较大,配置起来copy&paste让人觉得不太爽,比较臃肿。

下面的是Feiing给出的更好的方案,我有一些修改:

 

代码
  1. <beans>    
  2.         <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->    
  3.     <bean id="transactionManager"           class="org.springframework.orm.hibernate3.HibernateTransactionManager">    
  4.           <property name="sessionFactory">    
  5.               <ref bean="sessionFactory"/>    
  6.           </property>    
  7.     </bean>           
  8.            
  9.         <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">    
  10.             <property name="transactionManager" ref="transactionManager"/>    
  11.             <property name="transactionAttributes">  
  12.                 <props>  
  13.                     <prop key="*">PROPAGATION_REQUIRED</prop>  
  14.                     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
  15.                 </props>  
  16.             </property>  
  17.         </bean>    
  18.            
  19.         <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">    
  20.                 <property name="beanNames">  
  21.                     <value>*Service,*Manager</value>  
  22.                 </property>  
  23.                 <property name="interceptorNames">    
  24.                         <list>    
  25.                                 <value>transactionInterceptor</value>    
  26.                                 <!--  
  27.                                  此处增加新的Interceptor
  28.                                  -->    
  29.                         </list>    
  30.                 </property>    
  31.         </bean>    
  32.   
  33.         <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">    
  34.           <property name="transactionInterceptor" ref="transactionInterceptor"/>    
  35.         </bean>    
  36.   
  37.         <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>  
  38.                    
  39. </beans>    

 

以后每次的增量是这一段:

代码
  1. <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>   

 

跟配置普通bean的方法一样,非常简洁、直观。对现有的Service接口也无须任何修改

我把Feiing的transactionAttributesSource改成叻transactionAttributes,并且将DefaultAdvisorAutoProxyCreator改成了BeanNameAutoProxyCreator,我觉得毕竟不是context下的每个bean都需要事务,只要在Service层做AOP就可以叻。