完整版來叻!!
下面的是Feiing給出的更好的方案,我有一些修改:
Java代碼
- <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>
以後每次的增量是這一段: Java代碼
- <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>