为节省你的时间, 如果你你不清楚什么是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框架中,@Transactional注解是通过AOP代理来实现事务管理的。在默认情况下,只有外部调用目标方法时,Spring才会生成代理对象来管理事务。但是,如果在同一个类中的其他方法调用有@Transactional注解的方法...
在Spring中,我们主要使用`@Transactional`注解来声明一个方法需要进行事务管理。 ```java @Aspect @Component public class TransactionAspect { @Transactional public void someServiceMethod() { // 业务...
Spring 框架中 @Transactional 注解的工作原理分析 在 Spring 框架中,@Transactional 注解是一个非常重要的概念,经常用于数据库操作。那么,@Transactional 注解是如何工作的呢?让我们深入源码分析。 首先,从 ...
如果使用@Service 注解注释的类没有被 Spring 容器管理,那么即使方法被@Transactional 注解修饰,事务也不会生效。例如,StudentServiceImpl 类没有被 Spring 容器管理,因此即使方法被@Transactional 注解修饰,...
在这种方式下,我们不再需要为每个Bean创建代理,而是直接在需要事务的方法上使用@Transactional注解。这需要开启基于注解的事务管理,并配置相应的TransactionManager。示例配置如下: ```xml ``` 然后在...
在Spring中,可以使用@Transactional注解来标记需要进行事务管理的方法。例如: ```java @Service public class UserService { @Transactional public void updateUserAndOrder(User user, Order order) { ...
在Spring框架中,声明式事务管理是实现事务处理的一种高效且灵活的方式,它允许开发者通过XML配置或注解来定义事务边界,而无需在业务逻辑代码中显式地调用开始、提交或回滚事务的方法。这篇博文"Spring使用XML配置...
3. **切点定义**:虽然在注解方式中通常不需要显式定义切点,但如果你需要更复杂的切点逻辑,可以创建一个切点类,用`@Aspect`注解标识,并使用`@Pointcut`定义切点。 4. **事务规则绑定**:通过`@Transactional`...
Spring提供了一套基于TaskExecutor的异步任务处理机制,结合@Transactional注解,可以在异步执行的代码块中使用声明式事务管理。但这需要开发者对异步执行的事务特性有充分理解,因为事务的同步特性可能会受到影响。...
Spring 声明式事务是指使用 Spring 框架提供的声明式事务管理机制,以便简化事务处理的复杂度。声明式事务可以通过配置文件或注解的方式来实现事务管理。例如,使用 @Transactional 注解来标注事务方法。 @Aspect ...
5. **Spring Boot的自动配置**:在Spring Boot项目中,通过@EnableTransactionManagement和适当的依赖,Spring Boot能自动配置DataSource和TransactionManager,并且可以通过@Transactional注解进行事务控制。...
基于 AspectJ 的 AOP 代理方式可以让我们在类或方法上直接使用 @Transactional 注解来声明事务。 第三种方式:基于接口的代理 在这种方式下,我们需要让业务层的接口与实现类分别定义,并在接口上使用 @...
在Spring MVC或Spring Boot应用中,可以使用`@Transactional`注解在控制器方法上,让容器自动处理事务。这种方式下,事务的传播行为、隔离级别、读写模式等都可通过注解的属性进行配置。 4. Spring Data JPA与事务...
Spring提供了四种不同的方式来配置声明式事务,这使得事务管理更加灵活且易于维护。下面将详细介绍这四种方式。 1. **基于XML的TransactionProxyFactoryBean** 这是最常见的一种方式,通过`...
这样,带有@Transactional注解的类或方法将会自动地被Spring事务代理处理。 3. **编程式事务管理** 编程式事务管理允许在代码中显式地开始、提交、回滚事务。使用PlatformTransactionManager接口的实现,如...
- @Transactional注解:在方法或类级别使用,声明方法属于哪个事务范围。 - AspectJ注解驱动:结合AspectJ,可以在编译时或加载时织入事务控制逻辑。 - Annotation-driven配置:在Spring应用上下文中启用注解驱动...
它提供了五种不同的配置方式来适应不同的应用场景。以下是对这些配置方式的详细解释: 1. **基于代理的事务管理(Proxy-based Transaction Management)** 在第一种配置方式中,每个业务 Bean 都有一个代理。`...
例如,使用@Transactional注解标记在方法上,Spring会自动处理事务的开始、提交或回滚。 在实际应用中,为了使Spring能够识别和处理AspectJ切面,还需要在Spring配置文件中启用AspectJ自动代理,并添加相应的Bean...
Spring也支持使用@Transactional注解来声明事务边界。这种方式下,需要启用组件扫描并配置一个`AspectJTransactionManagementConfiguration`类,以让Spring识别并处理这些注解。 ```xml ...
5. **@Transactional注解**:这是声明式事务管理的关键,可以在方法上使用,表示该方法应该在一个事务内运行。注解可以指定事务属性,如隔离级别、传播行为等。 6. **TransactionInterceptor**:Spring AOP的拦截器...