在 Spring AOP 中,通知(Advice)的顺序是由通知的类型和声明的顺序决定的。Spring AOP 提供了几种不同类型的通知,包括前置通知、后置通知、环绕通知、异常通知和最终通知。它们的执行顺序主要依赖于通知的类型和它们在配置中声明的顺序。
通知类型及其执行顺序
前置通知(@Before):在方法执行前执行。
- 执行顺序:最先执行。
环绕通知(@Around):在方法执行前后都能执行,可以控制方法是否被调用。
- 执行顺序:如果存在
@Around
通知,它会在前置通知之前执行(如果有的话),并且在后置通知和异常通知之前执行。@Around
通知可以选择是否调用目标方法,并在调用前后执行自定义的逻辑。
- 执行顺序:如果存在
后置通知(@AfterReturning):在方法成功执行后(即没有抛出异常时)执行。
- 执行顺序:在方法执行完毕后(目标方法调用返回之后)执行,紧随环绕通知后。
异常通知(@AfterThrowing):在方法抛出异常时执行。
- 执行顺序:仅在目标方法抛出异常时执行,位于后置通知之后。
最终通知(@After):无论方法是否抛出异常,都会执行。
- 执行顺序:最后执行,不管目标方法是否成功或抛出异常。
执行顺序的总结:
- 前置通知(@Before):最先执行。
- 环绕通知(@Around):在前置通知之后,目标方法执行之前。环绕通知的
proceed()
方法调用才会触发目标方法。 - 后置通知(@AfterReturning):在目标方法成功执行后执行。
- 异常通知(@AfterThrowing):仅在目标方法抛出异常时执行,位于后置通知之后。
- 最终通知(@After):无论方法是否成功执行或抛出异常,都会最后执行。
注意事项:
@Around
通知的执行顺序要比其他通知更为灵活,因为它可以选择是否执行目标方法,并且决定目标方法执行的时机。- 如果
@Around
通知中没有显式调用proceed()
,目标方法是不会被调用的,因此后续的通知(如后置通知、异常通知等)将不会执行。
示例代码:
@Aspect
@Component
public class MyAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice() {
System.out.println("Before method execution");
}
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Around before method execution");
Object result = joinPoint.proceed();
System.out.println("Around after method execution");
return result;
}
@AfterReturning("execution(* com.example.service.*.*(..))")
public void afterReturningAdvice() {
System.out.println("After method execution (if successful)");
}
@AfterThrowing("execution(* com.example.service.*.*(..))")
public void afterThrowingAdvice() {
System.out.println("After method threw an exception");
}
@After("execution(* com.example.service.*.*(..))")
public void afterAdvice() {
System.out.println("After method execution (always)");
}
}
执行顺序会是:
beforeAdvice
(前置通知)aroundAdvice
的前半部分(环绕通知,在目标方法之前)- 目标方法的执行
aroundAdvice
的后半部分(环绕通知,在目标方法之后)afterReturningAdvice
(后置通知,如果没有抛出异常)afterAdvice
(最终通知,始终执行)
如果目标方法抛出异常:
beforeAdvice
(前置通知)aroundAdvice
的前半部分(环绕通知,在目标方法之前)- 异常发生
afterThrowingAdvice
(异常通知)afterAdvice
(最终通知,始终执行)
总结:
Spring AOP 的通知顺序是通过通知类型以及它们的声明顺序来决定的。通过合理配置不同类型的通知,可以实现灵活的 AOP 行为。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。