引言
在 Spring Boot 应用开发中,切面编程(AOP)是一项强大的功能,它允许我们将横切关注点(如日志记录、事务管理、权限控制等)从业务逻辑中分离出来,以提高代码的可维护性和可扩展性。当存在多个切面时,了解和控制切面的执行优先级顺序就显得尤为重要。本文将深入介绍 Spring Boot 框架中切面执行优先级顺序的使用方式。
切面优先级的概念
在 Spring AOP 中,切面的优先级决定了多个切面在目标方法执行前后的执行顺序。高优先级的切面会先于低优先级的切面执行。在环绕通知(@Around)中,高优先级切面的通知方法先进入,后退出;而在前置通知(@Before)中,高优先级切面的通知方法先执行,后置通知(@After)和返回后通知(@AfterReturning)以及异常通知(@AfterThrowing)则相反,低优先级切面的通知方法先执行。
优先级设置方式
@Order`注解
- 作用:在切面类上标注
@Order
,数值越小优先级越高。 - 示例:
@Aspect
@Component
@Order(1) // 优先级高于 Order(2) 的切面
public class LogAspect {
// 切面逻辑
}
- 规则:
- 未标注
@Order
的切面默认优先级最低(数值最大)。 - 同一优先级下,切面执行顺序由类名或方法名的字典序决定。
- 未标注
实现 Ordered
接口
- 作用:通过重写 getOrder()方法动态设置优先级
- 示例:
@Aspect
@Component
public class ValidationAspect implements Ordered {
@Override
public int getOrder() {
return 2; // 优先级低于返回 1 的切面
}
}
执行顺序规则
同一连接点的多个切面
- 前置通知(@Before):优先级高的切面先执行。
- 后置通知(@After、@AfterReturning、@AfterThrowing):优先级高的切面后执行。
- 环绕通知(@Around):优先级高的切面外层包裹优先级低的切面。
示例场景
假设切面 OrderDemoAspect1(优先级1), OrderDemoAspect2(优先级2),OrderDemoAspect3(优先级2)和 OrderDemoAspect4(默认优先级)作用于同一方法:
- OrderDemoAspect1的
@Around 开始
→ - OrderDemoAspect1的
@Before
→ - OrderDemoAspect2的 @Around 开始 →
- OrderDemoAspect2的
@Before
→ - OrderDemoAspect3的 @Around 开始 →
- OrderDemoAspect3的 @Before →
- OrderDemoAspect4 @Around 开始 →
- OrderDemoAspect4 @Before →
- OrderDemoAspect4 @AfterRunning →
- OrderDemoAspect4 @After →
- OrderDemoAspect4 @Around 结束 →
- OrderDemoAspect3 @AfterRunning →
- OrderDemoAspect3 @After →
- OrderDemoAspect3 @Around 结束 →
- OrderDemoAspect2 @AfterRunning →
- OrderDemoAspect2 @After →
- OrderDemoAspect2 @Around 结束 →
- OrderDemoAspect1 @AfterRunning →
- OrderDemoAspect1 @After →
- OrderDemoAspect1 @Around 结束 →
代码示例
多切面优先级配置
@Aspect
@Component
@Order(1)
public class OrderDemoAspect1 {
@Before("@annotation(com.shore.annotation.OrderDemoAnnotation)")
public void before() {
System.out.println("OrderDemoAspect1 before");
}
@After("@annotation(com.shore.annotation.OrderDemoAnnotation)")
public void after() {
System.out.println("OrderDemoAspect1 after");
}
@After