本文章比较了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>