`
bencmai
  • 浏览: 37006 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

用 AspectJ 方式来处理 Spring 的 @Transactional 注解式事务

阅读更多

为节省你的时间, 如果你你不清楚什么是Spring 、AspectJ、事务处理,本文就不适合你看。你可以路过就走。

 

在网络应用中,我们几乎总是需要严密控制我们spring应用中的数据库事务的启动和结束。为做到这一点,我们或多或少都已经通过AOP来做这些事情。但一般都是在XXService、或XXController中封装处理请求的方法。

Spring有内置注解支持,因而你可以简单地通过@Transactional 注解你的方法或类,并在配置文件中添加<tx:annotation-driven />,把相应方法封装于一个事务之中。这听起来好像很简单

 

但是,所有这些都是通过Spring 的代理对象封装并环绕增强原来的被注解@Transactional 的类来实现的,但这种做法只有当事务方法是public的、并且是被代理类外部调用的情况下才会正常工作(可以参看Spring 事务处理模型图就明白,否则代理对象自己调用自己就会绕过对它的环绕事务增强,其他切面增强也是一样)。这就很不爽了,意味着你不能在XXService或XXController内部串联处理一些具各自独立的事务,例如在XXController调用handleRequestInternal。解决的办法是使用全功能完整成熟的AspectJ织入。AspectJ织入方式同样支持@Transactional (其他自定义注解也行^_^),同时能被织入到所有方法中(不只是public),并且在内不外部都可以。

 

AspectJ有三种方式织入事务代码

a.编译时(CTW). 拥有所有需要的源代码

b.运行时(LTW).

c.字节码织入(BTW).没有织入目标的源代码(如只有jar)

 

这里我们使用CTW的方式

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop">

    <aop:spring-configured>

    <bean id="annotationTransactionAspect" factory-method="aspectOf"  class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>

    <!-- the rest of your application here -->
</beans>

 上面就是所有让Spring 使用Aspectj 方式@Transactional 注解事务的所有配置了。

 

下面我们开始把环绕事务切面的增强代码织入到注解了@Transactional  的XXService、或XXController类中(其他任何注解了@Transactional  也可以)。我们使用ant来构建织入。我们写一个ant任务来做这件事

<target name="compileAndWeave">

    <path id="web-src.compile.class.path">
        <!-- 指定编译时所需要的任意库, 包括AspectJ所需要的jar -->
        <path refid="external.libs.path" />
    </path>

    <!-- 正常地编译你的源代码到这个目录中-->
    <javac srcdir="src"  destdir="build/classes-preweave"  classpathref="web-src.compile.class.path" />

    <!-- 查找"iajc" task -->
    <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"  classpath="path/to/aspectj/aspectjtools.jar"/>

    <!-- weave the just compiled classes from classes-preweave into classes -->
    <iajc  inpath="build/classes-preweave"
             destdir="build/classes"                                          <!--正常javac编译的*.class文件,也就是我们注解了@Transactional  的XXService、或XXController类所在位置-->
             aspectpath="path/to/spring/spring-aspects.jar"   <!--AspectJ切面类所在位置如:org.springframework.transaction.aspectj.AnnotationTransactionAspect切面的位置-->
             classpathref="web-src.compile.class.path"     
            verbose="true" />

</target>

  

 编译后把你的war发布到任何web容器中他就能工作了,所有注解了@Transactional  的方法(各种可见度)都能正常的处理事务,如果是类级@Transactional  注解,该类的就所有public方法都有事务。而且被注解类的内外都能调用,这样,你完全可以撇开spring那麻烦的代理了,还补充一句,如果你使用了DWR做为你的ajax后台的话,服务层如果是JDK代理的话,将无法工作。只能使用Cglib方式的代理。还有很多情况,Spring 代理模式和其他一些框架配合工作的时候会有问题,全部使用AspectJ,撇开Spring 代理模式,你会觉得真的很free。

 

祝你好运!!

分享到:
评论

相关推荐

    Spring+Hibernate事务管理

    Spring将事务管理分成了两类: * 编程式事务管理 * 手动编写代码进行事务管理.(很少使用) * 声明式事务管理: * 基于TransactionProxyFactoryBean的方式.(很少使用) * 需要为每个进行事务管理的类,配置一个...

    Spring中文帮助文档

    6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.6.1. 理解AOP代理 6.7. 以编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ进行domain ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1....

    Spring API

    6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.6.1. 理解AOP代理 6.7. 以编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ进行domain ...

    Spring.3.x企业应用开发实战(完整版).part2

    9.6.1 使用@Transactional注解 9.6.2 通过AspectJ LTW引入事务切面 9.7 集成特定的应用服务器 9.7.1 BEA WebLogic 9.7.2 BEA WebLogic 9.8 小结 第10章 Spring的事务管理难点剖析 10.1 DAO和事务管理的牵绊 10.1.1 ...

    spring chm文档

    6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 ...

    Spring 2.0 开发参考手册

    6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 ...

    Spring3.x企业应用开发实战(完整版) part1

    9.6.1 使用@Transactional注解 9.6.2 通过AspectJ LTW引入事务切面 9.7 集成特定的应用服务器 9.7.1 BEA WebLogic 9.7.2 BEA WebLogic 9.8 小结 第10章 Spring的事务管理难点剖析 10.1 DAO和事务管理的牵绊 10.1.1 ...

    spring-transaction

    Spring将事务管理分成了两类 编程式事务管理 手动编写代码进行事务管理.(很少使用) 声明式事务管理 基于TransactionProxyFactoryBean的方式.(很少使用) 需要为每个进行事务管理的类,配置一个...

    Spring攻略(第二版 中文高清版).part1

    3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案 115 3.2.3 工作原理 116 3.3 访问...

    Spring攻略(第二版 中文高清版).part2

    3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案 115 3.2.3 工作原理 116 3.3 访问...

    spring_MVC源码

    弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...

Global site tag (gtag.js) - Google Analytics