在做基于aop的拦截controller入参并记录日志和基于aop的自定义注解来实现校验参数这两个功能时遇到了这个问题,就是当两个或多个aop同时作用于同一个方法时的执行顺序是什么。答案是,根据这个切面的设定顺序,这个设定的顺序越小则越先执行,目前设定顺序主要有三种方式:
- 实现org.springframework.core.Ordered接口,重写getOrder方法。
@Component
@Aspect
public class MessageQueueAopAspect implements Ordered{
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 2;
}
}
- 使用order注解指定顺序。
@Component
@Aspect
@Order(1)
public class MessageQueueAopAspect1{
...
}
- 通过配置文件配置设定顺序。
<aop:config expose-proxy="true">
<aop:aspect ref="aopBean" order="0">
<aop:pointcut id="testPointcut" expression="@annotation(xxx.xxx.xxx.annotation.xxx)"/>
<aop:around pointcut-ref="testPointcut" method="doAround" />
</aop:aspect>
</aop:config>
经实验确定,确实是order越小越是最先执行,但更重要的是最先执行的最后结束。下面我们通过看一个图会更直观:
Spring aop就是一个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP1、AOP2的顺序依次执行doAround方法,doBefore方法。然后执行method方法,最后按照AOP2、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来说,先before的,一定后after。
然后下面两个更清晰些:
- 同一aspect,不同advice的执行顺序
- 不同aspect,advice的执行顺序