【障礙再現】
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>元素中“聲明的順序”相關,即先聲明的切面類先執行,后聲明的切面類后執行