如果有多个通知在同一连接点执行,那执行顺序如何确定呢?
总共有两种情况:同一切面中通知执行顺序、不同切面中的通知执行顺序。
1、同一切面中通知执行顺序
1)前置通知/环绕通知proceed方法之前部分
2)被通知方法
3)后置通知/环绕通知proceed方法之后部分
annotation方式的顺序:环绕通知proceed方法之前部分---->前置通知---->被通知方法---->后置通知---->环绕通知proceed方法之后部分(多次测试结果显示如此,不知道具体原因)
XML配置方式:由配置顺序决定,例如
<aop:aspect id="aopLogAspect" ref="logAspect"> <aop:pointcut id="logApectPointcut" expression="execution(* test1.dao.*.add*(..))|| execution(* test1.dao.*.delete*(..))|| execution(* test1.dao.*.update*(..))|| execution(* test1.dao.*.load*(..))" /> <aop:before method="logStart" pointcut-ref="logApectPointcut" /> <aop:after method="logEnd" pointcut-ref="logApectPointcut" /> <aop:around method="logAround" pointcut-ref="logApectPointcut" /> </aop:aspect>
执行顺序是:前置通知---->环绕通知proceed方法之前部分---->被通知方法---->环绕通知proceed方法之后部分---->后置通知。其中before与around配置先后顺序会影响执行顺序,而after与around配置先后顺序则不会。(这是什么原因?)
2、不同切面中的通知执行顺序
当定义在不同切面的相同类型的通知需要在同一个连接点执行,如果没指定切面的执行顺序,这两个通知的执行顺序将是未知的。
如果需要他们顺序执行,可以通过指定切面的优先级来控制通知的执行顺序。
annotation方式:
1)@Order(int)指定优先级,例如@Order(1)---->@Order(2)
2)也可以通过在切面实现类上实现org.springframework.core.Ordered接口,由private int order 来指定优先级
XMl配置方式:可以由aop:aspect的order属性来指定,例如
<aop:aspect id="aopLogAspect" ref="logAspect" order="1" > ...... </aop:aspect> <aop:aspect id="aopTransactionAspect" ref=transactionAspect" order="2" > ...... </aop:aspect>
aopLogAspect ----> aopTransactionAspect
补充:测试结果显示,默认顺序由XML配置先后顺序决定,例如上面的例子去掉order属性及其值,执行顺序不变。那么问题来了,“当定义在不同切面的相同类型的通知需要在同一个连接点执行,如果没指定切面的执行顺序,这两个通知的执行顺序将是未知的。”这句话是否正确?在annotation方式中没错,但XML配置方式却是...从测试结果来看,执行顺序似乎是确定的,是否真的如此,有待考证。