本文章比較了Spring自己帶的JPetStore的例子,通過配置文件詳細講解了,Spring1.2.8與2.0如何實現聲明式事務管理。
Spring1.2.8
Spring以前對一個事務攔截要通過代理實現下面的配置文件是從不同的文件中找來的,不是單獨的一個Spring配置文件。
?<!-- Transaction manager for a single JDBC DataSource -->
?<!-- 聲明一個事務管理器 -->
?<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
??<property name="dataSource" ref="dataSource"/>
?</bean>
?<!-- 聲明一個抽象Bean,這個Bean是不能實例化的,提供給其它需要AOP事務的Bean用,其它需要AOP事務的只要繼承這個Bean就會被AOP接管-->
?<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
??? abstract="true">
??<property name="transactionManager" ref="transactionManager"/>
??<property name="transactionAttributes">
???<props>
????<prop key="insert*">PROPAGATION_REQUIRED</prop>
????<prop key="update*">PROPAGATION_REQUIRED</prop>
????<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
???</props>
??</property>
?</bean>
?<!-- 繼承之前實現的抽象Bean,讓這個Bean通過代理工廠生成,交給AOP托管。至于哪些方法被接管在控制Bean中已經配置了-->
?<bean id="petStore" parent="baseTransactionProxy">
??<property name="target">
???<bean class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
????<property name="accountDao" ref="accountDao"/>
????<property name="categoryDao" ref="categoryDao"/>
????<property name="productDao" ref="productDao"/>
????<property name="itemDao" ref="itemDao"/>
????<property name="orderDao" ref="orderDao"/>
???</bean>
??</property>
??<!-- Uncomment the following in order to enable mail sending aspect -->
??<!--
??<property name="postInterceptors">
???<list>
????<ref bean="emailAdvisor"/>
???</list>
??</property>
???-->
?</bean>
最早發表于 http://www.openj.cn
Spring2.0?
?下面的配置與上面的配置完全對應
?<!--這一個Bean的配置與之前完全一樣,沒有變化---->
?<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
??<property name="dataSource" ref="dataSource"/>
?</bean>
?<!--這一處與之前有了變化,在1.2.8版本中,此處的Bean被聲明為由一個FactoryBean生成,而此處只是一個普通的Bean,要簡單許多,透明性要好很多---->
?<bean id="petStore" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
??<property name="accountDao" ref="accountDao"/>
??<property name="categoryDao" ref="categoryDao"/>
??<property name="productDao" ref="productDao"/>
??<property name="itemDao" ref="itemDao"/>
??<property name="orderDao" ref="orderDao"/>
?</bean>
?<!---下面的兩處配置,才是整個事務AOP的核心,在1.2.8版本中,通過FactoryBean把事務對象(dataSource),與需要進行事務控制的對象PetStoreImpl串起來,對PetStoreImpl有侵入性----->
?<!---而在之前的兩處配置中,事務對象(dataSource)與,需要進行事務控制的對象PetStoreImpl沒有什么關系,它們的關系全部體現在下面的兩處配置中----->
?
?
?<!---pointcut屬性定義了哪此點需要去攔截,此處的配置的意思是所有的PetStoreFacade接口中的方法都要攔截,而攔截之后要如何處理則由advice-ref指定的Bean處理----->
?<!---配置文件中各個屬性的含義參考:http://www.redsaga.com/spring_ref/2.0/html/aop.html#aop-schema ----->
?<aop:config>
??<aop:advisor pointcut="execution(* *..PetStoreFacade.*(..))" advice-ref="txAdvice"/>?
?</aop:config>
?
?<!--下面的transaction-manager屬性原配置中沒有,如果缺少此配置,默認值就是“transactionManager”在此加上,讓人看的更明白。-->
?<!-- 參考 http://blog.xmnow.cn/doc/cn/spring2.0-reference_final_zh_cn/ch09s05.html --->
?<tx:advice id="txAdvice"? transaction-manager="transactionManager">
??<tx:attributes>
???<tx:method name="insert*"/>
???<tx:method name="update*"/>
???<tx:method name="*" read-only="true"/>
??</tx:attributes>
?</tx:advice>