用BeanNameAutoProxyCreator 自动创建事务代理

 下面介绍-种优秀的事务代理配置策略,采用这种配置策略,完全可以避免增量式配置,使所有的事务代理由系统自动创建。由于容器中的目标bean 自动消失,可避免需要使用嵌套bean 来保证目标bean 不可被访问。
       这种配置方式依赖于Spring 提供的bean 后处理器,该后处理器用于为每个bean 自动创建代理,此处的代理不仅可以是事务代理,也可以是任意的代理,只需要有合适的拦截器即可。这些是AOP 框架的概念,笔者在此处不AOP 进行深入介绍。读者只需了解这种事务代理的配置方式即可。
下面是采用 BeanNameAutoProxyCreator 配置事务代理的配置文件:
<?xml version="1.0" encoding="gb2312"?>
<!一Spring 配置文件的文件头,包含DTD 等信息-->
<lDOCTYPE beans PUBLIC "-IISPRINGIIDTD BEANIIEN"
''http://www. spr工ngfrarnework.org/dtd/spring-beans.dtd">
<beans>
<!- - 定义数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!一定义数据库驱动一>
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<!-- 定义数据库url-->
<property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
<!-- 定义数据库用户名-->
<property name= "username" ><value>root</value></property>
<!-- 定义数据库密码-->
<property name="password"><value>32147</value></property>
</bean>
<!--定义一个hibernate 的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSess工onFactoryBean">
<!-- 定义SessionFactory必须注入DataSource-->
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<!--以下用来列出所有的PO 映射文件-->
<value>Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--此处用来定义hibernate 的SessionFactory的属性:不同数据库连接启动时选择create , update , create-drop-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!--定义事务管理器,使用适用于Hibernate 的事务管理器-->
<bean id="transactionManager"
class="org.springfrarnework.orm.hibernate3.HibernateTransactionManager">
<!-- HibernateTransactionManager bean 需要依赖注入一个SessionFactory bean 的引用-->
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<!-- 配置事务拦截器-->
<bean id="transactionInterceptor" class="org.springfrarnework.transaction.interceptor.Transactionnterceptor">
<!-- 事务拦截器bean 需要依赖注入一个事务管理器-->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttr工butes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="insert*">PROPAGATION_REQ工URED</prop>
<prop key="find*">PROPAGATION_REQUIRED , readOnly</prop>
<prop key="*">PROPAGAT工ON_REQUIRED</prop>
</props>
</property>
</bean>
<!--定义BeanNameAutoProxyCreator ,该bean 是个bean 后处理器,无须被引用,因此没有id 属性这个bean 后处理器,根据事务拦截器为目标bean 自动创建事务代理-->
<bean class="org.spr工ngframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
指定对满足哪些bean name 的bean 自动生成业务代理>
<property name="beanNames">
<!--下面是所有需要自动创建事务代理的bean-->
<list>
<value>personDao</value>
</list>
<!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<!一下面定义BeanNameAutoProxyCreator所需的事务拦截器一〉
<property name=" interceptorNames">
<list>
<value>transactionlnterceptor</value>
<!--此处可增加其他新的工nterceptor -->
</list>
</property>
</bean>
<!--定义DAO Bean ,由于BeanNameAutoProxyCreator自动生成事务代理-->
<bean id="personDao" class="lee.PersonDaoHibernate">
<property name="sess工onFactory"><ref local="sessionFactory"I><1property>
</bean〉
</beans>
       TranscationInterceptor是一个事务拦截器bean,需要传入一个TransactionManager的引用。配置中使用 Spring 依赖注入该属性,事务拦截器的事务属性通过transactionAttributes 来指定,该属性有props 子元素,并在配置文件中定义了三个事务传播规则。
       所有以insert 开始的方法,都采用PROPAGATION_REQUIRED的事务传播规则。当程序抛出MyException异常及其子异常时,会自动回滚事务:所有 以find 开头的方法,都采用PROPAGATION_REQUIRED事务传播规则,并且具有只读性;其他方法则采用PROPAGATION_REQUIRED的 事务传播规则。BeanNameAutoProxyCreator是根据bean 名生成自动代理的代理创建器,该bean 通常需要接受两个参数:第一个是beanNames 属性,该属性用来设置哪些bean 需要自动生成代理,另一个属性是interceptorNames,该属性则指定事务拦截器,在自动创建事务代理时,系统会根据这些事务拦截器的属性来生 成对应的事务代理。
       为了让读者对这种配置方式有信息,可PersonDaoHibemate的save 方法进行简单修改,修改后的save 方法如下:
/**
*保存person 实例
* @param person 需要保存的Person 实例
*/
public void save(Person person)
{
getHibernateTemplate() .save(person);
//下面两行代码没有实际意义,仅仅为了引发数据库异常
DataSource ds = null;
DataSourceUtils.getConnection(ds);
在主程序中调用该save 方法,主程序调用save 方法的代码如下:
for(int i = 0 ; i < 10 ; i++ )
{
// 保存Person 实例
pdao.save(new Person(String.valueOf(i) , i + 10));
执行完主程序的该片段后,数据库不会插入任何记录。如果BeanNameAutoProxyCreator 的配置修改成如下格式:
<! --定义BeanNameAutoProxyCreator,该bean 是个bean 后处理器,无须被引用,因此没有id 属性这个bean 后处理器,根据事务拦截器为目标bean 自动创建事务代理-->
<bean c1ass="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--指定对满足哪些bean name 的bean 自动生成业务代理-->
<property name="beanNames">
<!--下面是所有需要自动创建事务代理的bean-->
<list>
<!-- va1ue>personDao</va1ue-->
</list>
<!一此处可增加其他需要自动创建事务代理的bean-->
</property>
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</va1ue >
<!--此处可增加其他新的Interceptor -->
</list>
</property>
</bean>
注意配置文中beanNames属性的变化,将所有 personDao项加注释,即不再为该bean生成事务代理。再次执行主程序,此时程序虽然抛出了数据库异常,但数据记录依然被插入数据库。
这种配置方式相当简洁,每次都增加了新的bean。如果需要该bean 的方法具有事务性,只需在BeanNameAutoProxyCreator 的beanNames 属性下作相应修改。该行告诉bean 后处理需要为哪个bean 生成事务代理。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值