下面的是Feiing给出的更好的方案,我有一些修改:
- <beans>
- <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA); -->
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory">
- <ref bean="sessionFactory"/>
- </property>
- </bean>
- <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager" ref="transactionManager"/>
- <property name="transactionAttributes">
- <props>
- <prop key="*">PROPAGATION_REQUIRED</prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
- </props>
- </property>
- </bean>
- <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="beanNames">
- <value>*Service,*Manager</value>
- </property>
- <property name="interceptorNames">
- <list>
- <value>transactionInterceptor</value>
- <!--
- 此处增加新的Interceptor
- -->
- <!--value>exceptionHandler</value>
<value>timeHandler</value-->
</list>
</property>
</bean>
<!-- Advice 负责记录有异常发生时的信息-->
<bean id="exceptionHandler" class="com.unsap.dec.platform.util.ExceptionHandler"/>
<bean id="exceptionHandlereAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="exceptionHandler"/>
</property>
<!--对指定类的任何方法有效-->
<property name="patterns">
<value>.*.*</value>
</property>
</bean>
<!-- Advice 负责记录方法的记录时间-->
<bean id="timeHandler" class="com.unsap.dec.platform.util.TimeHandler"/>
<bean id="timeHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="timeHandler"/>
</property>
<!--对指定类的任何方法有效-->
<property name="patterns">
<value>.*.*</value>
</property>
</bean> - <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
- <property name="transactionInterceptor" ref="transactionInterceptor"/>
- </bean>
- <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>
- </beans>
<beans>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA); -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>*Service,*Manager</value>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
<!--
此处增加新的Interceptor
-->
</list>
</property>
</bean>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>
</beans>
以后每次的增量是这一段:
- <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>
<bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>
跟配置普通bean的方法一样,非常简洁、直观。 对现有的Service接口也无须任何修改
我把Feiing的transactionAttributesSource改成叻transactionAttributes,并且将DefaultAdvisorAutoProxyCreator改成了BeanNameAutoProxyCreator,我觉得毕竟不是context下的每个bean都需要事务,只要在Service层做AOP就可以叻。
和Robbin一致认为,Feiing的做法非常可取,因为它 分离叻XML配置文件关注点
受hongliang启发,我现在就用这个方法,但是发现一个Bug。里面代理匹配的名字有*Manager,就是想匹配所有的ManagerObject。但是好像没有注意到,这样配置会把transactionManager也匹配上,然后定义的是find以外的方法都是要事务的。也就说transactionManager执行getTransaction的时候还会要事务,然后就是死循环,造成溢出。。
我解决的办法就是transactionManager改称transactionManagerHibernate。这么做的时候一定要注意名字的问题。别一不小心,把一个不相关的东东给弄进来的。。。
对了,加Acegi的时候有很多*Manager,打算想一个比较好名字匹配。。
=======================================================================
<bean id="transactionAdmin" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionAdmin"/>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="query*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="beanNames">
<list>
<value>*Manager*</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<bean id="exceptionHandler" class="com.unsap.dec.platform.util.ExceptionHandler"/>
<bean id="timeHandler" class="com.unsap.dec.platform.util.TimeHandler"/>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="beanNames">
<list>
<value>*Manager*</value>
<value>*Action*</value>
<value>*Dao*</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>exceptionHandler</value>
<value>timeHandler</value>
</list>
</property>
</bean>