【原】Order屬性決定了不同切面類中通知執行的先后順序


【障礙再現】

    MyBatis配置多數據源時,數據源切換失敗。

【原因分析】
    自定義切面和Spring自帶事務切面“即<aop:advisor>”執行的先后順序導致數據源不能切換成功。

【解決方案】
1、配置代碼

1 <aop:config>                    
2     <!-- 1、Spring框架自身提供的切面 -->
3     <aop:advisor advice-ref="userTxAdvice" pointcut="execution(public * com.zjrodger.*.service..*.*(..))" order="2"/>                                
4     <!-- 2、用戶自定義的切面,根據切入點,動態切換數據源。 -->        
5     <aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor" order="1">                                        
6         <aop:before method="setdataSourceBakDb"  pointcut="execution(* com.zjrodger.bakdata.service..*.*(..))"/>                        
7         <aop:before method="setdataSourceHuihangDb"  pointcut="execution(* com.zjrodger.datatobank.service..*.*(..))"/>    
8     </aop:aspect>        
9 </aop:config>
不同AOP切面類的配置

2、說明

    在AOP中,當執行同一個切入點時,不同切面的執行先后順序是由“每個切面的order屬性”而定的,order越小,則該該切面中的通知越先被執行。
上述<aop:config>元素中,引用了兩個切面類:“userTxAdvice類”和“dataSourceAspect類”,其中<aop:advisor>是Spring框架自定義的切面標簽。
根據兩個切面類order屬性的定義,當程序執行時並且觸發切入點后(即調用
com.zjrodger.bakdata.service包及其子包下的方法),dataSourceAspect切面類中的setdatasourceBakDb()方通知法首先執行,之后才會執行userTxAdvice事務類中的相關通知方法。

【拓展】
若不想設置Order屬性,如何能決定不同切面類中通知執行的先后順序?
答:可以調整,在不定義Order屬性的前提下,可以通過切面類的定義順序來決定通知執行的先后順序。
    但需要特別注意的是,若<aop:config>元素中同時存在“<aop:advisor>”元素和“<aop:aspect>元素”(“<aop:pointcut>元素” 可有可無),則它們元素必須按照< aop:pointcut >,<aop:advisor>和<aop:aspect>此順序來定義
    正因為“<aop:advisor>”元素和“<aop:aspect>元素”定義順序是不能調整的,從而導致在沒有指定 “order屬性”的前提下,“<aop:advisor>”元素對應切面類中通知的執行順序優先於“<aop:aspect>元素” 對應切面類中通知的執行。
    此時,只能通過指定Order屬性來調整這兩個切面類中通知執行的先后順序了。

【結論】
(1)在AOP中,當執行同一個切入點時,不同切面的執行先后順序是由“每個切面的order屬性”而定的,order越小,則該該切面中的通知越先被執行。

(2)不定義Order屬性,通過切面類的定義順序來決定通知執行的先后順序
若不同切面類執行時,在沒有定義“order屬性”,而且切面類中觸發增強通知的切入點都相同,則在切面類中的通知的執行順序與該切面類在<aop:config>元素中“聲明的順序”相關,即先聲明的切面類先執行,后聲明的切面類后執行

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM