申明:本文轉載至https://www.cnblogs.com/zjrodger/p/5633922.html,如有侵權,請及時告知,本人将立即删除。
【障礙再現】
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>
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>元素中“聲明的順序”相關,即先聲明的切面類先執行,後聲明的切面類後執行