spring事务,方法拦截器各种配置

1.代理工厂Bean事务管理(*ProxyFactoryBean)+Service+DAO配置

我刚开始看Spring时用的书是林信良的《Spring技术手册》,书中对声明式事务主要采用TransactionProxyFactoryBean,业务Bean如Service或BO类继承它来进行事务控制。代理工厂Bean(*ProxyFactoryBean)这一类Spring提供的工厂类,可将一个bean进行委托代理,从而达到控制方法行为的目的。

此类事务配置一般如下(因为我们未采用这种方式,就以书上的JDBCdatasource举例说明。不同公司采用的格式可能有所不同):

Xml代码

<!--前面的dataSource等配置略........-->

<!--事务管理器-->

<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<propertyname="dataSource">

<reflocal="dataSource"/>

</property>

</bean>

<!--事务模板-->

<beanid="baseTransactionProxy"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

abstract="true">

<propertyname="transactionManager"ref="transactionManager"/>

<propertyname="transactionAttributes">

<props>

<propkey="*">PROPAGATION_REQUIRED</prop><!--本文仅简单用一种方式说明。所有方法起事务,可以修改以精细和区别性控制事务-->

</props>

</property>

</bean>

<!--业务对象-->

<beanid="authService"parent="baseTransactionProxy">

<propertyname="target">

<beanclass="com.xxxx.cms.service.AuthorityService">

<propertyname="authDao"ref="authDao"/>

</bean>

</property>

</bean>

<beanid="departmentService"parent="baseTransactionProxy">

<propertyname="target">

<beanclass="com.xxxx.cms.service.pojo.DepartmentService">

<propertyname="departmentDao"ref="departmentDao"/>

</bean>

</property>

</bean>

<!--数据访问对象-->

<beanid="authDao"class="com.xxxx.cms.dao.jdbc.AuthorityDao">

<propertyname="dataSource"ref="dataSource"/>

</bean>

<beanid="departmentDao"class="com.xxxx.cms.dao.jdbc.DepartmentDao">

<propertyname="dataSource"ref="dataSource"/>

</bean>

<!--前面的dataSource等配置略........-->

<!--事务管理器-->

<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<propertyname="dataSource">

<reflocal="dataSource"/>

</property>

</bean>

<!--事务模板-->

<beanid="baseTransactionProxy"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

abstract="true">

<propertyname="transactionManager"ref="transactionManager"/>

<propertyname="transactionAttributes">

<props>

<propkey="*">PROPAGATION_REQUIRED</prop><!--本文仅简单用一种方式说明。所有方法起事务,可以修改以精细和区别性控制事务-->

</props>

</property>

</bean>

<!--业务对象-->

<beanid="authService"parent="baseTransactionProxy">

<propertyname="target">

<beanclass="com.xxxx.cms.service.AuthorityService">

<propertyname="authDao"ref="authDao"/>

</bean>

</property>

</bean>

<beanid="departmentService"parent="baseTransactionProxy">

<propertyname="target">

<beanclass="com.xxxx.cms.service.pojo.DepartmentService">

<propertyname="departmentDao"ref="departmentDao"/>

</bean>

</property>

</bean>

<!--数据访问对象-->

<beanid="authDao"class="com.xxxx.cms.dao.jdbc.AuthorityDao">

<propertyname="dataSource"ref="dataSource"/>

</bean>

<beanid="departmentDao"class="com.xxxx.cms.dao.jdbc.DepartmentDao">

<propertyname="dataSource"ref="dataSource"/>

</bean>

这种代理工厂Bean的事务管理一般都要求将Service的bean配置为class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean",上面的例子使用了parent="baseTransactionProxy"继承机制简化了原书中的配置。

代码中通过以下方式使用:

Java代码

AuthServiceauthService=(AuthService)context.getBean("authService");

booleanb=authService.hasPermission("TOKEN_XXXXX");

AuthServiceauthService=(AuthService)context.getBean("authService");

booleanb=authService.hasPermission("TOKEN_XXXXX");

2.自动代理事务(*AutoProxyCreator)+Service+DAO配置

*AutoProxyCreator这一类东东,能够自动为Spring容器中的bean进行AOP代理,配置起来能适当简化。一般需要用BeanNameAutoProxyCreator来配置对那些类进行自动代理,MethodPointcutAdvisor来配置对哪些方法进行代理。

这种声明式事务配置采用拦截器(Interceptor)或通知器(Advisor)进行事务控制,这里使用了Spring提供的TransactionInterceptor来管理事务。(本质上ProxyFactoryBean也要生成被代理对象的字节码,不过每个类型的ProxyFactoryBean只能固定处理一个Aspect,不算真正的AOP)。

以下配置对*Service的所有方法进行事务控制。

<beanid="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<propertyname="sessionFactory">

<reflocal="sessionFactory"/>

</property>

</bean>

Xml代码

<!--事务管理拦截器-->

<beanid="transactionInterceptor"class="org.springframework.transaction.interceptor.TransactionInterceptor">

<propertyname="transactionManager">

<reflocal="transactionManager"/>

</property>

<propertyname="transactionAttributes">

<props>

<propkey="*">PROPAGATION_REQUIRED</prop><!--本文仅简单用一种方式说明。所有方法起事务,还可以精细控制事务-->

</props>

</property>

</bean>

<!--配置要拦截哪些方法-->

<beanid="trasactionMethodPointcutAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

<propertyname="mappedNames">

<list>

<value>*</value><!--所有方法-->

</list>

</property>

<propertyname="advice">

<reflocal="transactionInterceptor"/>

</property>

</bean>

<!--配置要拦截哪些类,并使用那些拦截器-->

<beanid="ServiceAutoProxyCreator"class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<propertyname="proxyTargetClass"value="true"></property>

<propertyname="beanNames">

<list>

<value>*Service</value>

</list>

</property>

<propertyname="interceptorNames">

<list>

<!--头三个是我们项目中用的其他Advisor,这里展示了添加拦截器进行aspect控制的灵活性。省略他们的配置-->

<value>monitorMethodPointcutAdvisor</value>

<value>asynmonitorMethodPointcutAdvisor</value>

<value>businessLogMethodPointcutAdvisor</value>

<value>trasactionMethodPointcutAdvisor</value><!--事务拦截器,直接配成transactionInterceptor去掉trasactionMethodPointcutAdvisorbean也可以,-->

</list>

</property>

</bean>

<!--事务管理拦截器-->

<beanid="transactionInterceptor"class="org.springframework.transaction.interceptor.TransactionInterceptor">

<propertyname="transactionManager">

<reflocal="transactionManager"/>

</property>

<propertyname="transactionAttributes">

<props>

<propkey="*">PROPAGATION_REQUIRED</prop><!--本文仅简单用一种方式说明。所有方法起事务,还可以精细控制事务-->

</props>

</property>

</bean>

<!--配置要拦截哪些方法-->

<beanid="trasactionMethodPointcutAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

<propertyname="mappedNames">

<list>

<value>*</value><!--所有方法-->

</list>

</property>

<propertyname="advice">

<reflocal="transactionInterceptor"/>

</property>

</bean>

<!--配置要拦截哪些类,并使用那些拦截器-->

<beanid="ServiceAutoProxyCreator"class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<propertyname="proxyTargetClass"value="true"></property>

<propertyname="beanNames">

<list>

<value>*Service</value>

</list>

</property>

<propertyname="interceptorNames">

<list>

<!--头三个是我们项目中用的其他Advisor,这里展示了添加拦截器进行aspect控制的灵活性。省略他们的配置-->

<value>monitorMethodPointcutAdvisor</value>

<value>asynmonitorMethodPointcutAdvisor</value>

<value>businessLogMethodPointcutAdvisor</value>

<value>trasactionMethodPointcutAdvisor</value><!--事务拦截器,直接配成transactionInterceptor去掉trasactionMethodPointcutAdvisorbean也可以,-->

</list>

</property>

</bean>

Service,DAO的配置方式稍微改变一下,Service不再作为ProxyFactoryBean的target属性,而是一个顶级bean,这样Servicebean看起来就更单纯一些。

Xml代码

<!--业务对象-->

<beanclass="com.xxxx.cms.service.AuthorityService">

<propertyname="authDao"ref="authDao"/>

</bean>

<beanclass="com.xxxx.cms.service.pojo.DepartmentService">

<propertyname="departmentDao"ref="departmentDao"/>

</bean>

<!--数据访问对象-->

<beanid="authDao"class="com.xxxx.cms.dao.jdbc.AuthorityDao">

<propertyname="dataSource"ref="dataSource"/>

</bean>

<beanid="departmentDao"class="com.xxxx.cms.dao.jdbc.DepartmentDao">

<propertyname="dataSource"ref="dataSource"/>

</bean>

相关推荐