zoukankan      html  css  js  c++  java
  • 事务(九)

    Spring AOP的执行顺序

    众所周知,spring声明式事务是基于AOP实现的,那么,如果我们在同一个方法自定义多个AOP,我们如何指定他们的执行顺序呢?

    配置AOP执行顺序的三种方式

    通过实现org.springframework.core.Ordered接口

     1 @Component  
     2 @Aspect  
     3 @Slf4j  
     4 public class MessageQueueAopAspect1 implements Ordered{@Override  
     5     public int getOrder() {  
     6         // TODO Auto-generated method stub  
     7         return 2;  
     8     }  
     9       
    10 }

    通过注解

    1 @Component  
    2 @Aspect  
    3 @Slf4j  
    4 @Order(1)  
    5 public class MessageQueueAopAspect1{  
    6       
    7     ...  
    8 }

    通过配置文件配置

    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

    测试代码

     1 @Component  
     2 @Aspect  
     3 @Slf4j  
     4 public class MessageQueueAopAspect1 implements Ordered{  
     5       
     6     @Resource(name="actionMessageProducer")  
     7     private IProducer<MessageQueueInfo> actionProducer;     
     8       
     9     @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire1)")  
    10     private void pointCutMethod() {  
    11     }  
    12       
    13     //声明前置通知  
    14     @Before("pointCutMethod()")  
    15     public void doBefore(JoinPoint point) {  
    16         log.info("MessageQueueAopAspect1:doBefore");  
    17         return;  
    18     }  
    19   
    20     //声明后置通知  
    21     @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")  
    22     public void doAfterReturning(JoinPoint point,Object returnValue) {  
    23         log.info("MessageQueueAopAspect1:doAfterReturning");  
    24     }  
    25   
    26     //声明例外通知  
    27     @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")  
    28     public void doAfterThrowing(Exception e) {  
    29         log.info("MessageQueueAopAspect1:doAfterThrowing");  
    30     }  
    31   
    32     //声明最终通知  
    33     @After("pointCutMethod()")  
    34     public void doAfter() {  
    35         log.info("MessageQueueAopAspect1:doAfter");  
    36     }  
    37   
    38     //声明环绕通知  
    39     @Around("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       
    47     @Override  
    48     public int getOrder() {  
    49         return 1001;  
    50     }  
    51 }
     1 @Component  
     2 @Aspect  
     3 @Slf4j  
     4 public class MessageQueueAopAspect2 implements Ordered{  
     5       
     6     @Resource(name="actionMessageProducer")  
     7     private IProducer<MessageQueueInfo> actionProducer;     
     8       
     9     @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire2)")  
    10     private void pointCutMethod() {  
    11     }  
    12       
    13       
    14     //声明前置通知  
    15     @Before("pointCutMethod()")  
    16     public void doBefore(JoinPoint point) {  
    17         log.info("MessageQueueAopAspect2:doBefore");  
    18         return;  
    19     }  
    20   
    21     //声明后置通知  
    22     @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")  
    23     public void doAfterReturning(JoinPoint point,Object returnValue) {  
    24         log.info("MessageQueueAopAspect2:doAfterReturning");  
    25     }  
    26   
    27     //声明例外通知  
    28     @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")  
    29     public void doAfterThrowing(Exception e) {  
    30         log.info("MessageQueueAopAspect2:doAfterThrowing");  
    31     }  
    32   
    33     //声明最终通知  
    34     @After("pointCutMethod()")  
    35     public void doAfter() {  
    36         log.info("MessageQueueAopAspect2:doAfter");  
    37     }  
    38   
    39     //声明环绕通知  
    40     @Around("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       
    48     @Override  
    49     public int getOrder() {  
    50         return 1002;  
    51     }  
    52 }

    测试结果

    从上面的测试我们看到,确实是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里边处理自己的业务逻辑。

    转载:https://www.cnblogs.com/fanguangdexiaoyuer/p/10562069.html

    带着疑问去思考,然后串联,进而归纳总结,不断追问自己,进行自我辩证,像侦查嫌疑案件一样看待技术问题,漆黑的街道,你我一起寻找线索,你就是技术界大侦探福尔摩斯
  • 相关阅读:
    软件部门每年耗资大约100亿到200多亿美元,但没有研发出任何具有说服力的产品,因此华为决定关闭
    Qt Model/View理解(二)---构造model(细心研读,发现超简单,Model就是做三件事:返回行数量、列数量、data如何显示。然后把model与view联系起来即可,两个例子都是如此)good
    linux 下用find命令查找文件,rm命令删除文件
    北电之死:谁谋杀了华为的对手?——银湖资本(Silver Lake)董事总经理爱德华·詹德出任CEO,既不了解华为,也不重视中国,直截了当地否决了收购华为
    搞定JavaScript正则表达式
    Orleans3.0
    CSS盒模型
    作用域和闭包
    NServiceBus是.Net平台下的开源的消息服务框架
    [1]System.Reflection.Emit
  • 原文地址:https://www.cnblogs.com/cainiao-Shun666/p/14531315.html
Copyright © 2011-2022 走看看