spring aop 和Transaction一起使用执行顺序问题

本文探讨了在使用AOP进行方法拦截时,如何解决事务提交前先执行自定义切面的问题。通过调整AOP执行顺序,确保事务管理正确执行。文章详细介绍了Spring中不同通知类型的执行顺序,帮助理解程序正常及异常情况下的执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开发中遇到,aop拦截事物方法,先执行了,自己写的切面,Transaction还没提交

原因:spring Transaction也是aop实现,spring 先执行了自己定义的切面aop

解决方法:设置aop执行顺序,order越小越先执行

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="0"/>

@Component
@Aspect
@Order(1)
public class YourAspect

 

 

网上摘抄了一段各注解执行顺序,待测

Spring 中通知的类型:

Around     org.aopalliance.intercept.MethodInterceptor                栏截对目标对象方法的调用 
Before      org.springframework.aop.MethodBeforAdvice             在目标方法被调用之前调用    
After          org.springframework.aop.AfterReturningAdvice          当目标方法被调用之后调用

Thorws    org.springframework.aop.ThrowsAdvice                       当目标方法抛出异常时调用

程序正常执行顺序:

执行前 -环绕通知                                              Around

执行前 - 通知                                                    Before

POINT - 切入点 方法前执行                               @Before

POINT - 切入点 环绕方法前执行                       @Around

POINT - 切入点 方法后执行                               @AfterReturning

POINT - 切入点 环绕方法后执行                       @Around

执行后 - 通知                                                    After        

执行后 - 环绕通知                                            Around

程序抛出异常执行顺序:

执行前 -环绕通知                                              Around

执行前 - 通知                                                    Before

POINT - 切入点 方法前执行                               @Before

POINT - 切入点 环绕方法前执行                       @Around

切入点异常处理通知                                             @AfterThrowing

异常处理通知                                                          Thorws

<think>好的,用户想了解Spring AOP使用指南或原理介绍。首先,我需要回顾一下Spring AOP的基础知识,确保自己理解正确。Spring AOP是基于代理实现的,分为JDK动态代理CGLIB代理,这点要讲清楚。然后,用户可能需要知道如何实际应用,比如如何定义切面、切入点、通知类型等。 接下来,用户提供的引用资料中提到了一些关键点,比如AOP的应用场景、事务处理、执行顺序等。需要把这些信息整合到回答中,确保覆盖原理、使用方法常见问题。比如引用[2]提到Spring AOP利用反射代理模式,这部分应该在原理部分详细说明。 用户可能不太清楚具体怎么开始使用,所以需要给出一个简单的示例,展示如何创建切面通知。比如使用@Aspect注解定义切入点表达式。同时,要提到配置类需要@EnableAspectJAutoProxy,这点很重要,不然用户可能会遇到切面不生效的问题。 另外,引用[3]中的执行顺序需要解释清楚,不同通知类型的执行顺序对开发调试有帮助,可能会影响日志记录或事务管理。引用[4]的事务处理可以作为一个应用场景的例子,说明如何通过AOP管理事务。 还要注意用户可能遇到的常见问题,比如代理失效的情况,内部方法调用不走代理,这时候需要解释原因并提供解决方案,比如使用AopContext.currentProxy()。此外,性能优化方面,引用[1]提到要合理选择策略,所以可以建议优先使用JDK代理,必要时切换CGLIB。 最后,生成相关问题时要覆盖原理、使用、优化常见问题,帮助用户进一步学习。需要确保所有LaTeX格式正确,数学表达式用$...$,独立公式用$$...$$,但看起来当前内容中可能没有需要用到复杂数学公式的地方,不过如果有提到性能分析中的时间复杂度,可能需要用到,比如快速排序的平均复杂度是$O(n \log n)$,但这里可能不适用,所以可能不需要。但根据用户之前的示例,可能用户希望有相关问题,所以按照要求生成相关问题即可。</think>### Spring AOP使用指南与原理解析 #### 一、核心原理 1. **代理机制** Spring AOP通过动态代理实现横切逻辑的织入: - **JDK动态代理**:基于接口实现,要求目标类必须实现至少一个接口[^2] - **CGLIB代理**:通过继承生成子类代理,适用于无接口的类[^2] $$ \text{代理选择逻辑} = \begin{cases} \text{JDK代理} & \text{目标类实现接口} \\ \text{CGLIB代理} & \text{目标类未实现接口} \end{cases} $$ 2. **织入时机** 采用**运行时织入**(Runtime Weaving),通过字节码操作在方法调用时动态增强逻辑[^3] #### 二、基础使用 1. **环境配置** ```xml <!-- Maven依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 2. **切面定义** ```java @Aspect @Component public class LoggingAspect { // 定义切入点:匹配所有Service层方法 @Pointcut("execution(* com.example.service.*.*(..))") public void serviceLayer() {} // 前置通知 @Before("serviceLayer()") public void logMethodStart(JoinPoint joinPoint) { System.out.println("方法执行开始: " + joinPoint.getSignature()); } } ``` 3. **启用AOP** ```java @Configuration @EnableAspectJAutoProxy public class AppConfig {} ``` #### 三、高级特性 1. **通知类型** | 通知类型 | 执行时机 | 典型应用场景 | |---------------|-----------------------------|---------------------| | @Before | 目标方法执行前 | 权限校验、日志记录 | | @AfterReturning | 方法正常返回后 | 结果处理 | | @AfterThrowing | 方法抛出异常时 | 异常监控 | | @After | 方法最终结束(类似finally) | 资源清理 | | @Around | 包裹整个方法执行过程 | 性能监控、事务管理 [^4] | 2. **执行顺序控制** ```java @Aspect @Order(1) // 数字越小优先级越高 public class SecurityAspect { // 优先执行的切面逻辑 } ``` #### 四、最佳实践 1. **切入点表达式优化** - 使用`@annotation`定位特定注解方法: ```java @Around("@annotation(com.example.AsyncTask)") ``` - 组合表达式: ```java @Pointcut("execution(* *..service.*.*(..)) && @annotation(org.springframework.transaction.annotation.Transactional)") ``` 2. **代理失效场景处理** ```java // 当内部方法调用不走代理时: public class OrderService { public void createOrder() { // 错误方式:直接调用不会触发AOP // this.validateStock(); // 正确方式:通过代理对象调用 ((OrderService)AopContext.currentProxy()).validateStock(); } } ``` #### 五、性能优化建议 1. 优先使用JDK动态代理,必要时切换CGLIB: ```properties spring.aop.proxy-target-class=false ``` 2. 避免在切面中执行耗时操作 3. 使用条件表达式减少匹配范围[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值