切面1
@Component
@Aspect
@Slf4j
@Order(1)
public class Aspect1 {
@Pointcut("execution(* com.example.demo.aop.AopRest.testAop(..))")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("aspect1 before");
Object[] args = joinPoint.getArgs();
args[0] = "aspect1";
Object proceed = joinPoint.proceed(args);
log.info("aspect1 after");
return proceed;
}
}
切面2
@Component
@Aspect
@Slf4j
@Order(2)
public class Aspect2 {
@Pointcut("execution(* com.example.demo.aop.AopRest.testAop(..))")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("aspect2 before");
Object[] args = joinPoint.getArgs();
args[0] = "aspect2";
Object proceed = joinPoint.proceed(args);
log.info("aspect2 after");
return proceed;
}
}
切点方法
@RestController
@RequestMapping("/aop")
@Slf4j
public class AopRest {
@GetMapping("/test")
public void testAop(String aop){
log.info("method --"+aop);
}
}
执行结果

总结
- 使用 @Order 或 Ordered 接口可以明确控制通知的执行顺序。
- 最后一个切面执行真正的方法
- 环绕通知执行顺序遵循“先进入后退出”的嵌套规则。
- 如果没有显式顺序,执行顺序由 Spring 容器决定,不应依赖。
其它场景1:切面2提前return
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("aspect2 before");
Object[] args = joinPoint.getArgs();
args[0] = "aspect2";
if(true){
return null;
}
Object proceed = joinPoint.proceed(args);
log.info("aspect2 after");
return proceed;
}
执行结果
- 按正常流程切面2执行真正的方法,可是执行前return了,导致真正的方法也没执行,切面1的后处理仍会执行

其它场景2:切面1提前return
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("aspect1 before");
Object[] args = joinPoint.getArgs();
args[0] = "aspect1";
if(true){
return null;
}
Object proceed = joinPoint.proceed(args);
log.info("aspect1 after");
return proceed;
}
执行结果
- 可见切面1执行了before直接结束,切面2未执行,因为还没开始嵌套

其它场景3:抛异常