在 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 行為。