文章目錄
- 1.Spring基于XML的通知執行順序
- 1.1.XML檔案配置說明
- 1.2.各種通知說明
- 1.3.在配置同一個切入點且不出現異常時的執行順序
- 1.4.情況一
- 1.2.情況二
- 1.3.情況三
- 1.4.情況四
- 1.5.小結
- 2.Spring基于注解的通知執行順序
- 2.1.正常情況
- 2.2.異常情況
- 2.3.探究順序錯誤的真相
- 2.4.結論
1.Spring基于XML的通知執行順序
1.1.XML檔案配置說明
圖檔來源:《Java EE企業級應用開發教程》
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiQDOxEzX3xCZlhXam9VbsUmepNXZy9CXwJWZ3xCdh1mcvZ2Lc1zaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLwIzX39GZhh2csATMflHLwEzX4xSZz91ZsAzMfRHLGZkRGZkRfJ3bs92YskmNhVTYykVNQJVMRhXVEF1X0hXZ0xiNx8VZ6l2cssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLxEzNxMGN4IDO4EjMwQmYyYzX4IzM1kDMwMzLcZDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
1.2.各種通知說明
配置前置通知:在切入點方法執行之前執行
配置後置通知(傳回通知):在切入點方法正常執行之後執行。它和異常通知永遠隻能執行一個
配置異常通知:在切入點方法執行産生異常之後執行。它和後置通知永遠隻能執行一個
配置最終通知:無論切入點方法是否正常執行,它都會在其後面執行
配置環繞通知:可以在代碼中手動控制增強方法何時執行
注意:後置通知和最終通知的差別:後置通知時在方法成功執行後會執行的,如果出現異常就不執行。而最終通知時無論是否出現異常都會執行的,感覺類似于finally
1.3.在配置同一個切入點且不出現異常時的執行順序
注意,橢圓中順序不固定,具體順序與配置檔案的申明順序有關
1.4.情況一
<!--3.2.配置通知-->
<aop:aspect ref="tx">
<!--前置通知-->
<aop:before method="openTx" pointcut-ref="pointcut"/>
<!--環繞通知-->
<aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
<!--後置通知(傳回通知)-->
<aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
<!--最終通知-->
<aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
<!--異常通知-->
<aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>
順序:
1.2.情況二
<!--3.2.配置通知-->
<aop:aspect ref="tx">
<!--環繞通知-->
<aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
<!--前置通知-->
<aop:before method="openTx" pointcut-ref="pointcut"/>
<!--後置通知(傳回通知)-->
<aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
<!--最終通知-->
<aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
<!--異常通知-->
<aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>
順序:
結論一:前置通知和環繞通知的順序和申明順序有關,申明在前的先執行
1.3.情況三
<aop:aspect ref="tx">
<!--環繞通知-->
<aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
<!--前置通知-->
<!--<aop:before method="openTx" pointcut-ref="pointcut"/>-->
<!--後置通知(傳回通知)-->
<aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
<!--最終通知-->
<aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
<!--異常通知-->
<aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>
順序:
1.4.情況四
<aop:aspect ref="tx">
<!--環繞通知-->
<aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
<!--前置通知-->
<!--<aop:before method="openTx" pointcut-ref="pointcut"/>-->
<!--最終通知-->
<aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
<!--後置通知(傳回通知)-->
<aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
<!--異常通知-->
<aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>
順序:
1.5.小結
結論:Spring基于XML的申明式通知的執行順序與配置檔案中的申明順序有關
2.Spring基于注解的通知執行順序
我們在網上查找關于SpringAop執行順序的的資料,大多數時候,你會查到如下的答案:
2.1.正常情況
2.2.異常情況
上述測試結果是在Spring的5.2.6.RELEASE版本下進行測試,換成5.2.7.RELEASE版本測試結果就不同了!
2.3.探究順序錯誤的真相
于是去官網搜尋文檔,不得不說Spring由于過于龐大,官網的文檔已經到了冗雜的地步,不過最終還是找到了:
https://docs.spring.io/spring-framework/docs/5.2.9.RELEASE/spring-framework-reference/core.html#aop-ataspectj-advice-ordering
As of Spring Framework 5.2.7, advice methods defined in the same @Aspect class that need to run at the same join point are assigned precedence based on their advice type in the following order, from highest to lowest precedence: @Around, @Before, @After, @AfterReturning, @AfterThrowing.
翻譯重點:
從Spring5.2.7開始,在相同@Aspect類中,通知方法将根據其類型按照從高到低的優先級進行執行:@Around,@Before ,@After,@AfterReturning,@AfterThrowing。