Spring声明式事务是基于AOP实现的,那么,如果我们在同一个方法自定义多个AOP,我们如何指定他们的执行顺序呢?
首先:配置AOP执行顺序的三种方式:
1.通过实现org.springframework.core.Ordered接口
[email protected]??
[email protected]??
[email protected]??
4.public?class?MessageQueueAopAspect1?implements?Ordered{@Override??
5.????public?int?getOrder()?{??
6.????????//?TODO?Auto-generated?method?stub??
7.return?2;
8.????}??
9.??????
10.}??
2.通过注解
[email protected]??
[email protected]??
[email protected]??
[email protected](1)??
5.public?class?MessageQueueAopAspect1{??
6.??????
7.????...??
8.}??
3.通过配置文件配置
1.<aop:config?expose-proxy="true">??
2.????<aop:aspect?ref="aopBean"?order="0">????
3.????????<aop:pointcut?id="testPointcut"??expression="@annotation(xxx.xxx.xxx.annotation.xxx)"/>????
4.????????<aop:around?pointcut-ref="testPointcut"?method="doAround"?/>????
5.????????</aop:aspect>????
6.</aop:config>??
我们在同一个方法上加以下两个AOP,看看究竟。
[email protected]??
[email protected]??
[email protected]??
4.public?class?MessageQueueAopAspect1?implements?Ordered{??
5.??????
[email protected](name="actionMessageProducer")??
7.????private?IProducer<MessageQueueInfo>?actionProducer;?????
8.??????
[email protected]("@annotation(com.xxx.annotation.MessageQueueRequire1)")??
10.????private?void?pointCutMethod()?{??
11.????}??
12.??????
13.????//声明前置通知??
[email protected]("pointCutMethod()")??
15.????public?void?doBefore(JoinPoint?point)?{??
16.????????log.info("MessageQueueAopAspect1:doBefore");??
17.????????return;??
18.????}??
19.??
20.????//声明后置通知??
[email protected](pointcut?=?"pointCutMethod()",?returning?=?"returnValue")??
22.????public?void?doAfterReturning(JoinPoint?point,Object?returnValue)?{??
23.????????log.info("MessageQueueAopAspect1:doAfterReturning");??
24.????}??
25.??
26.????//声明例外通知??
[email protected](pointcut?=?"pointCutMethod()",?throwing?=?"e")??
28.????public?void?doAfterThrowing(Exception?e)?{??
29.????????log.info("MessageQueueAopAspect1:doAfterThrowing");??
30.????}??
31.??
32.????//声明最终通知??
[email protected]("pointCutMethod()")??
34.????public?void?doAfter()?{??
35.????????log.info("MessageQueueAopAspect1:doAfter");??
36.????}??
37.??
38.????//声明环绕通知??
[email protected]("pointCutMethod()")??
40.????public?Object?doAround(ProceedingJoinPoint?pjp)?throws?Throwable?{??
41.????????log.info("MessageQueueAopAspect1:doAround-1");??
42.????????Object?obj?=?pjp.proceed();??
43.????????log.info("MessageQueueAopAspect1:doAround-2");??
44.????????return?obj;??
45.????}??
46.??????
[email protected]??
48.????public?int?getOrder()?{??
49.????????return?1001;??
50.????}??
51.}??
[email protected]??
[email protected]??
[email protected]??
4.public?class?MessageQueueAopAspect2?implements?Ordered{??
5.??????
[email protected](name="actionMessageProducer")??
7.????private?IProducer<MessageQueueInfo>?actionProducer;?????
8.??????
[email protected]("@annotation(com.xxx.annotation.MessageQueueRequire2)")??
10.????private?void?pointCutMethod()?{??
11.????}??
12.??????
13.??????
14.????//声明前置通知??
[email protected]("pointCutMethod()")??
16.????public?void?doBefore(JoinPoint?point)?{??
17.????????log.info("MessageQueueAopAspect2:doBefore");??
18.????????return;??
19.????}??
20.??
21.????//声明后置通知??
[email protected](pointcut?=?"pointCutMethod()",?returning?=?"returnValue")??
23.????public?void?doAfterReturning(JoinPoint?point,Object?returnValue)?{??
24.????????log.info("MessageQueueAopAspect2:doAfterReturning");??
25.????}??
26.??
27.????//声明例外通知??
[email protected](pointcut?=?"pointCutMethod()",?throwing?=?"e")??
29.????public?void?doAfterThrowing(Exception?e)?{??
30.????????log.info("MessageQueueAopAspect2:doAfterThrowing");??
31.????}??
32.??
33.????//声明最终通知??
[email protected]("pointCutMethod()")??
35.????public?void?doAfter()?{??
36.????????log.info("MessageQueueAopAspect2:doAfter");??
37.????}??
38.??
39.????//声明环绕通知??
[email protected]("pointCutMethod()")??
41.????public?Object?doAround(ProceedingJoinPoint?pjp)?throws?Throwable?{??
42.????????log.info("MessageQueueAopAspect2:doAround-1");??
43.????????Object?obj?=?pjp.proceed();??
44.????????log.info("MessageQueueAopAspect2:doAround-2");??
45.????????return?obj;??
46.????}??
47.??????
[email protected]??
49.????public?int?getOrder()?{??
50.????????return?1002;??
51.????}??
52.}??
[email protected](propagation=Propagation.REQUIRES_NEW)??
[email protected]??
[email protected]??
4.public?PnrPaymentErrCode?bidLoan(String?id){??
5.??????????????...??
6.???????}??
看看执行结果:
从上面的测试我们看到,确实是order越小越是最先执行,但更重要的是最先执行的最后结束。
这个不难理解,spring?AOP就是面向切面编程,什么是切面,画一个图来理解下:
? ? ? ? ?由此得出:spring aop就是一个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP1、AOP2的顺序依次执行doAround方法,doBefore方法。然后执行method方法,最后按照AOP2、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来说,先before的,一定后after。
? ? ? ? 如果我们要在同一个方法事务提交后执行自己的AOP,那么把事务的AOP order设置为2,自己的AOP order设置为1,然后在doAfterReturn里边处理自己的业务逻辑。
原文地址:http://blog.51cto.com/13587708/2136504
时间: 2024-10-10 05:25:28