【原】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>元素中“声明的顺序”相关,即先声明的切面类先执行,后声明的切面类后执行

 

posted @ 2016-07-01 17:47  zjrodger  阅读(5725)  评论(0编辑  收藏  举报