Spring AOP Advice的顺序问题
Advice优先级与执行顺序的关系
当多个Advice作用于同一个JoinPoint的时候,他们的顺序是怎样的?在这个问题上,SpringAOP的优先级规则与AspectJ是相同的。优先级最高的在进入时先执行,但是在出去时最后执行。示例如下:

在调用被代理的方法时(进入时),优先级最高的Advice1会先被执行,紧接着是Advice2和Advice3。在从被代理的方法返回时,优先级最低的Advice3会被先执行,紧接着是Advice2和Advice1。
举几个例子:
如果Advice1、Advice2和Advice3都是BeforeAdvice,那么增强逻辑都是在proxied method执行前执行,那么Advice1、Advice2和Advice3按照优先级顺序执行。优先级最高的Advice1会先被执行,紧接着是Advice2和Advice3。
如果Advice1、Advice2和Advice3都是AfterAdice,那么增强逻辑都是在proxied method执行后执行,优先级最低的Advice3会先被执行,紧接着是Advice2和Advice1。
如果Advice1、Advice2和Advice3都是AroudAdvice,那么在proxied method执行前后都会有增强逻辑,其执行顺序是:Advice1的前部增强逻辑->Advice2的前部增强逻辑->Advice3的前部增强逻辑->proxied method ->Advice3的前部增强逻辑->Advice2的前部增强逻辑->Advice1的前部增强逻辑。
如何指定Advice优先级
Advice的优先级通过Aspect指定。切面类可以实现org.springframework.core.Ordered接口或者使用@Order注解来指定优先级。Order越低,优先级越高。位于不同的Aspect当中的Advice可以通过这种方式指定优先级。那么位于同一个Aspect内的Adivce的顺序呢?
位于同一个Aspect内的Adivce的顺序按照如下规则:
@Around->@Before->@After->@AfterReturning->@AfterThrowing
即AroudAdivce优先级最高,AfterThrowing优先级最低。
如果不同类型的Advice作用于同一个JoinPoint上,且这些Advice在同一个Aspect内,他们的执行顺序会是怎样的?比如这样的一个代码片段:
@Aspect
@Component
public class SimpleAspect {
@Before(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void before() {
System.out.println("before....");
}
@After(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void after() {
System.out.println("after....");
}
@AfterReturning(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void afterRet() {
System.out.println("after return....");
}
@AfterThrowing(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void afterThrow() {
System.out.println("after throwing....");
}
@Around(value = "execution(* com.lspring.beans..*.doSomething(..))")
public void doMonitor(ProceedingJoinPoint jp) {
System.out.println("Around before...");
try {
Object proceed = jp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("Around after...");
}
}
执行结果:
Around before...
before....
do something,name=10,age=18
after return....
after....
Around after...
JdkDynamicAopProxy产生的拦截器链如下:
- ExposeInvocationInterceptor
- AspectJAroundAdvice
- MethodBeforeAdviceInterceptor
- AspectJAfterAdvice
- AfterReturningAdviceInterceptor
- AspectJAfterThrowingAdvice
运行截图:

与执行结果相符。可以看出其执行顺序遵循如下顺序:
//around before
//@Before()
try {
try {
Object retVal = method.proceed();
// @AfterReturning
return retVal;
}catch (Exception e){
//@AfterThrowing
}
}finally {
// @After
}
// around after
将代码稍作修改:
@Aspect
@Component
public class AnotherAspect {
@After(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void after() {
System.out.println("after....");
}
@AfterReturning(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void afterRet() {
System.out.println("after return....");
}
@AfterThrowing(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void afterThrow() {
System.out.println("after throwing....");
}
}
@Aspect
@Component
public class SimpleAspect {
@Before(value = "execution(* com.lspring.beans..*.doSomething(..)) ")
public void before() {
System.out.println("before....");
}
@Around(value = "execution(* com.lspring.beans..*.doSomething(java.lang.String,java.lang.Integer))")
public void doMonitor(ProceedingJoinPoint jp) {
System.out.println("Around before...");
//System.out.println("age=" + a);
try {
Object proceed = jp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("Around after...");
}
}
获得的执行结果如下:
Around before...
before....
do something,name=10,age=18
Around after...
after return....
after....
JdkDynamicAopProxy产生的拦截器链如下:
- ExposeInvocationInterceptor
- AspectJAfterAdvice
- AfterReturningAdviceInterceptor
- AspectJAfterThrowingAdvice
- AspectJAroundAdvice
- MethodBeforeAdviceInterceptor
与执行结果相符。
浙公网安备 33010602011771号