目录
[一、默认执行顺序(无 @Order 注解时)](#一、默认执行顺序(无 @Order 注解时))
[二、使用 @Order 注解自定义顺序](#二、使用 @Order 注解自定义顺序)
@Order不设置的话是有默认值的

当有多个切面(Aspect)的切入点(Pointcut)都匹配到同一个目标方法时,在目标方法运行期间,这些切面中的通知(Advice)都会被执行。其执行顺序遵循以下规则:
一、默认执行顺序(无 @Order
注解时)
不同切面类中,默认按照切面类的类名按字母顺序排序:
- 前置通知(@Before):类名字母靠前的切面,先执行。
- 后置通知(@After / @AfterReturning) :类名字母靠前的切面,后执行。
🔍 示例:
假设有两个切面类:
MyAspect2
MyAspect3
按类名字母排序:
MyAspect2
<MyAspect3
所以:
@Before
通知执行顺序:MyAspect2 先执行,MyAspect3 后执行@After
通知执行顺序:MyAspect3 先执行,MyAspect2 后执行(逆序)
二、使用 @Order
注解自定义顺序
可以通过在切面类上添加 @Order(数字)
注解来显式控制执行顺序。
java
@Order(数字)
@Component
@Aspect
public class XxxAspect { ... }
- 数字越小,优先级越高。
- 前置通知(@Before) :
@Order
值小的切面先执行。 - 后置通知(@After) :
@Order
值小的切面后执行。
✅ 示例:
@Order(1)
的切面 A@Order(5)
的切面 B则:
@Before
执行顺序:A → B(数字小的先)@After
执行顺序:B → A(数字小的后)
三、代码示例
java
// MyAspect2.java
@Order(1)
@Component
@Aspect
@Slf4j
public class MyAspect2 {
@Before("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
public void before() {
log.info("before... 2");
}
@After("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
public void after() {
log.info("after... 2");
}
}
java
// MyAspect3.java
@Order(5)
@Component
@Aspect
@Slf4j
public class MyAspect3 {
@Before("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
public void before() {
log.info("before... 3");
}
@After("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
public void after() {
log.info("after... 3");
}
}
四、执行结果示例
调用目标方法时,输出日志顺序为:
java
before... 2 // @Order(1) 的 @Before 先执行
before... 3 // @Order(5) 的 @Before 后执行
【目标方法执行】
after... 3 // @Order(5) 的 @After 先执行
after... 2 // @Order(1) 的 @After 后执行
✅ 总结口诀:
- 前置通知:Order 小的先执行(越小越"前")
- 后置通知:Order 小的后执行(越小越"后")