切面优先级

    顾名思义,就是切面的优先级,比如当两个切面都是前置通知时,先执行哪一个。

    创建一个新类VlidationAspect.java

  

 

    看看结果:

   

 

    如果此时我想更改顺序,就需要在类名上使用@Order()注释,括号里的数值越小,优先级越高

    

 

    

 

    看看结果:

    

 

转载于:https://www.cnblogs.com/figsprite/p/10791111.html

### AOP切面优先级事务注解失效的影响及解决方法 #### 问题描述 当Spring应用中同时存在多个AOP切面(例如自定义日志切面、缓存切面等)时,如果这些切面优先级设置不当,可能会导致`@Transactional`注解的事务管理功能失效。具体表现为事务无法正常开启或回滚[^2]。 #### 原因分析 1. **事务切面优先级较低** Spring的事务管理依赖于代理机制,事务切面需要在其他切面前执行以确保事务上下文的正确创建和传播。如果自定义切面优先级高于事务切面,则可能导致事务上下文未被正确初始化或异常未被正确捕获,从而引发事务失效。 2. **异常处理不当** 如果自定义切面捕获了异常但未将其重新抛出,事务切面将无法感知到异常的发生,进而无法触发事务回滚逻辑[^2]。 3. **切面执行顺序无序** 在没有明确指定优先级的情况下,Spring会按照一定的规则决定切面的执行顺序。这种默认顺序可能不符合业务需求,导致事务切面无法正确嵌套在其他切面内部[^4]。 #### 解决方案 ##### 方法一:调整切面优先级 通过`@Order`注解或实现`Ordered`接口来明确指定切面优先级,确保事务切面优先执行。例如: ```java @Aspect @Order(1) // 数字越小,优先级越高 @Component public class TransactionAspect { @Around("@annotation(org.springframework.transaction.annotation.Transactional)") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { return joinPoint.proceed(); } } ``` 通过上述配置,可以保证事务切面在其他切面前执行,从而避免事务失效的问题。 ##### 方法二:手动控制事务 在自定义切面中手动管理事务,例如使用`TransactionStatus`和`PlatformTransactionManager`显式控制事务的提交或回滚。示例代码如下: ```java @Aspect @Component public class CustomAspect { @Autowired private PlatformTransactionManager transactionManager; @Around("@annotation(org.springframework.transaction.annotation.Transactional)") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { DefaultTransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(def); try { Object result = joinPoint.proceed(); transactionManager.commit(status); return result; } catch (Exception e) { transactionManager.rollback(status); throw e; } } } ``` 这种方式适用于需要深度干预事务管理的场景。 ##### 方法三:确保异常正确传播 在自定义切面中捕获异常后,必须将其重新抛出以确保事务切面能够感知到异常。例如: ```java @Aspect @Component public class LoggingAspect { @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "e") public void afterThrowing(JoinPoint joinPoint, Throwable e) throws Throwable { log.error("Exception in {} with args {}", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()), e); throw e; // 确保异常继续传播 } } ``` 通过这种方式,可以避免因异常被捕获而导致的事务失效问题[^2]。 ##### 方法四:合理设计切点 确保事务切点与自定义切点不冲突,并且事务切点能够覆盖所有需要事务管理的方法。例如: ```java @Pointcut("execution(* com.example.service..*(..))") public void serviceLayer() {} @Around("serviceLayer()") public Object aroundServiceLayer(ProceedingJoinPoint joinPoint) throws Throwable { return joinPoint.proceed(); } ``` 通过明确的切点定义,可以减少切面之间的干扰[^4]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值