`
bencmai
  • 浏览: 37488 次
  • 性别: 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。

 

祝你好运!!

分享到:
评论

相关推荐

    Java注解@Transactional事务类内调用不生效问题及解决办法

    在Spring框架中,@Transactional注解是通过AOP代理来实现事务管理的。在默认情况下,只有外部调用目标方法时,Spring才会生成代理对象来管理事务。但是,如果在同一个类中的其他方法调用有@Transactional注解的方法...

    spring基于AspectJ实现事务控制

    在Spring中,我们主要使用`@Transactional`注解来声明一个方法需要进行事务管理。 ```java @Aspect @Component public class TransactionAspect { @Transactional public void someServiceMethod() { // 业务...

    Spring源码学习十二:@Transactional是如何工作的1

    Spring 框架中 @Transactional 注解的工作原理分析 在 Spring 框架中,@Transactional 注解是一个非常重要的概念,经常用于数据库操作。那么,@Transactional 注解是如何工作的呢?让我们深入源码分析。 首先,从 ...

    详细整理Spring事务失效的具体场景及解决方案.docx

    如果使用@Service 注解注释的类没有被 Spring 容器管理,那么即使方法被@Transactional 注解修饰,事务也不会生效。例如,StudentServiceImpl 类没有被 Spring 容器管理,因此即使方法被@Transactional 注解修饰,...

    spring事务配置的5中方式

    在这种方式下,我们不再需要为每个Bean创建代理,而是直接在需要事务的方法上使用@Transactional注解。这需要开启基于注解的事务管理,并配置相应的TransactionManager。示例配置如下: ```xml ``` 然后在...

    Spring事务优缺点及使用详解.docx

    在Spring中,可以使用@Transactional注解来标记需要进行事务管理的方法。例如: ```java @Service public class UserService { @Transactional public void updateUserAndOrder(User user, Order order) { ...

    Spring使用XML配置声明式事务

    在Spring框架中,声明式事务管理是实现事务处理的一种高效且灵活的方式,它允许开发者通过XML配置或注解来定义事务边界,而无需在业务逻辑代码中显式地调用开始、提交或回滚事务的方法。这篇博文"Spring使用XML配置...

    spring_tx_aspectj方式源码

    3. **切点定义**:虽然在注解方式中通常不需要显式定义切点,但如果你需要更复杂的切点逻辑,可以创建一个切点类,用`@Aspect`注解标识,并使用`@Pointcut`定义切点。 4. **事务规则绑定**:通过`@Transactional`...

    全面分析_Spring_的编程式事务管理及声明式事务管理.

    Spring提供了一套基于TaskExecutor的异步任务处理机制,结合@Transactional注解,可以在异步执行的代码块中使用声明式事务管理。但这需要开发者对异步执行的事务特性有充分理解,因为事务的同步特性可能会受到影响。...

    Spring声明式事务和@Aspect的拦截顺序问题的解决

    Spring 声明式事务是指使用 Spring 框架提供的声明式事务管理机制,以便简化事务处理的复杂度。声明式事务可以通过配置文件或注解的方式来实现事务管理。例如,使用 @Transactional 注解来标注事务方法。 @Aspect ...

    详解Spring配置事务的五种方式

    5. **Spring Boot的自动配置**:在Spring Boot项目中,通过@EnableTransactionManagement和适当的依赖,Spring Boot能自动配置DataSource和TransactionManager,并且可以通过@Transactional注解进行事务控制。...

    Spring事务五种不同的代理配置

    基于 AspectJ 的 AOP 代理方式可以让我们在类或方法上直接使用 @Transactional 注解来声明事务。 第三种方式:基于接口的代理 在这种方式下,我们需要让业务层的接口与实现类分别定义,并在接口上使用 @...

    Spring事务管理的几种配置方式,

    在Spring MVC或Spring Boot应用中,可以使用`@Transactional`注解在控制器方法上,让容器自动处理事务。这种方式下,事务的传播行为、隔离级别、读写模式等都可通过注解的属性进行配置。 4. Spring Data JPA与事务...

    Spring中的四种声明式事务的配置

    Spring提供了四种不同的方式来配置声明式事务,这使得事务管理更加灵活且易于维护。下面将详细介绍这四种方式。 1. **基于XML的TransactionProxyFactoryBean** 这是最常见的一种方式,通过`...

    spring配置事务五种方式.doc

    这样,带有@Transactional注解的类或方法将会自动地被Spring事务代理处理。 3. **编程式事务管理** 编程式事务管理允许在代码中显式地开始、提交、回滚事务。使用PlatformTransactionManager接口的实现,如...

    Spring声明式事务配置管理方法

    - @Transactional注解:在方法或类级别使用,声明方法属于哪个事务范围。 - AspectJ注解驱动:结合AspectJ,可以在编译时或加载时织入事务控制逻辑。 - Annotation-driven配置:在Spring应用上下文中启用注解驱动...

    Spring事务配置的五种方式

    它提供了五种不同的配置方式来适应不同的应用场景。以下是对这些配置方式的详细解释: 1. **基于代理的事务管理(Proxy-based Transaction Management)** 在第一种配置方式中,每个业务 Bean 都有一个代理。`...

    aspectj-1.6.10.jar,aspectjweaver-1.6.9.jar,spring事务所用到的jar

    例如,使用@Transactional注解标记在方法上,Spring会自动处理事务的开始、提交或回滚。 在实际应用中,为了使Spring能够识别和处理AspectJ切面,还需要在Spring配置文件中启用AspectJ自动代理,并添加相应的Bean...

    Spring的事务配置的五种方式

    Spring也支持使用@Transactional注解来声明事务边界。这种方式下,需要启用组件扫描并配置一个`AspectJTransactionManagementConfiguration`类,以让Spring识别并处理这些注解。 ```xml ...

    spring-tx事物源码

    5. **@Transactional注解**:这是声明式事务管理的关键,可以在方法上使用,表示该方法应该在一个事务内运行。注解可以指定事务属性,如隔离级别、传播行为等。 6. **TransactionInterceptor**:Spring AOP的拦截器...

Global site tag (gtag.js) - Google Analytics