spring多个AOP执行先后顺序(面试问题:怎么控制多个aop的执行循序)
转载:spring多个AOP执行先后顺序(面试问题:怎么控制多个aop的执行循序)
众所周知,spring声明式事务是基于AOP实现的,那么,如果我们在同一个方法自定义多个AOP,我们如何指定他们的执行顺序呢?网上很多答案都是指定order,order越小越是最先执行,这种也不能算是错,但有些片面。
配置AOP执行顺序的三种方式
通过实现org.springframework.core.Ordered接口
@Component
@Aspect
@Slf4j
public class MessageQueueAopAspect1 implements Ordered{@Override
public int getOrder() {
// TODO Auto-generated method stub
return 2;
} }
通过注解
@Component
@Aspect
@Slf4j
@Order(1)
public class MessageQueueAopAspect1{ ...
}
通过配置文件配置
<aop:config expose-proxy="true">
<aop:aspect ref="aopBean" order="0">
<aop:pointcut id="testPointcut" expression="@annotation(xxx.xxx.xxx.annotation.xxx)"/>
<aop:around pointcut-ref="testPointcut" method="doAround" />
</aop:aspect>
</aop:config>
同一个方法上加以下两个AOP
测试代码
@Component
@Aspect
@Slf4j
public class MessageQueueAopAspect1 implements Ordered{ @Resource(name="actionMessageProducer")
private IProducer<MessageQueueInfo> actionProducer; @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire1)")
private void pointCutMethod() {
} //声明前置通知
@Before("pointCutMethod()")
public void doBefore(JoinPoint point) {
log.info("MessageQueueAopAspect1:doBefore");
return;
} //声明后置通知
@AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")
public void doAfterReturning(JoinPoint point,Object returnValue) {
log.info("MessageQueueAopAspect1:doAfterReturning");
} //声明例外通知
@AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
public void doAfterThrowing(Exception e) {
log.info("MessageQueueAopAspect1:doAfterThrowing");
} //声明最终通知
@After("pointCutMethod()")
public void doAfter() {
log.info("MessageQueueAopAspect1:doAfter");
} //声明环绕通知
@Around("pointCutMethod()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
log.info("MessageQueueAopAspect1:doAround-1");
Object obj = pjp.proceed();
log.info("MessageQueueAopAspect1:doAround-2");
return obj;
} @Override
public int getOrder() {
return 1001;
}
}
@Component
@Aspect
@Slf4j
public class MessageQueueAopAspect2 implements Ordered{ @Resource(name="actionMessageProducer")
private IProducer<MessageQueueInfo> actionProducer; @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire2)")
private void pointCutMethod() {
} //声明前置通知
@Before("pointCutMethod()")
public void doBefore(JoinPoint point) {
log.info("MessageQueueAopAspect2:doBefore");
return;
} //声明后置通知
@AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")
public void doAfterReturning(JoinPoint point,Object returnValue) {
log.info("MessageQueueAopAspect2:doAfterReturning");
} //声明例外通知
@AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
public void doAfterThrowing(Exception e) {
log.info("MessageQueueAopAspect2:doAfterThrowing");
} //声明最终通知
@After("pointCutMethod()")
public void doAfter() {
log.info("MessageQueueAopAspect2:doAfter");
} //声明环绕通知
@Around("pointCutMethod()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
log.info("MessageQueueAopAspect2:doAround-1");
Object obj = pjp.proceed();
log.info("MessageQueueAopAspect2:doAround-2");
return obj;
} @Override
public int getOrder() {
return 1002;
}
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
@MessageQueueRequire1
@MessageQueueRequire2
public PnrPaymentErrCode bidLoan(String id){
...
}
测试结果

从上面的测试我们看到,确实是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里边处理自己的业务逻辑。
spring多个AOP执行先后顺序(面试问题:怎么控制多个aop的执行循序)的更多相关文章
- Spring切面通知执行的顺序(Advice Order)
问题描述 如果在Spring的程序中同时定义了环绕通知(Around)和前置通知(Before)..那么,有以下问题: 1.怎么让两个切面通知都起作用 2.或者让两者切面按自己指定的顺序进行执行? 3 ...
- spring通知执行的顺序
点击下载本示例相关代码 关于spring aop的具体使用,暂时不在这里讲解,后面会特定来讲解,本次主要探讨spring中通知执行的顺序. spring中通知分为以下几种: before:前置通知,在 ...
- Spring系列26:Spring AOP 通知与顺序详解
本文内容 如何声明通知 如何传递参数到通知方法中 多种通知多个切面的通知顺序 多个切面通知的顺序源码分析与图解 声明通知 Spring中有5种通知,通过对应的注解来声明: @BeforeBefore ...
- spring3: AOP 之 通知顺序
如果我们有多个通知想要在同一连接点执行,那执行顺序如何确定呢?Spring AOP使用AspectJ的优先级规则来确定通知执行顺序.总共有两种情况:同一切面中通知执行顺序.不同切面中的通知执行顺序. ...
- 面试中AOP这样说,面试官只有一个字:服!
- Spring Security 入门(1-6-2)Spring Security - 内置的filter顺序、自定义filter、http元素和对应的filterChain
Spring Security 的底层是通过一系列的 Filter 来管理的,每个 Filter 都有其自身的功能,而且各个 Filter 在功能上还有关联关系,所以它们的顺序也是非常重要的. 1.S ...
- 曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 面试官:线程池如何按照core、max、queue的执行循序去执行?(内附详细解析)
前言 这是一个真实的面试题. 前几天一个朋友在群里分享了他刚刚面试候选者时问的问题:"线程池如何按照core.max.queue的执行循序去执行?". 我们都知道线程池中代码执行顺 ...
- 口述完SpringMVC执行流程,面试官就让同事回家等消息了
Srping MVC 执行流程真的是老生常谈的话题了,最近同事小刚出去面试,前面面试官相继问了几个 Spring 相关的问题,但当面试官问他,你知道 Srping MVC 的执行流程吗?小刚娴熟的巴拉 ...
随机推荐
- Java 字符串常用操作(String类)
字符串查找 String提供了两种查找字符串的方法,即indexOf与lastIndexOf方法. 1.indexOf(String s) 该方法用于返回参数字符串s在指定字符串中首次出现的索引位置, ...
- 【Ruby】【高级编程】正则
#[[正则]]=beginsub 和 gsub 及它们的替代变量 sub! 和 gsub! 是使用正则表达式时重要的字符串方法.所有这些方法都是使用正则表达式模式执行搜索与替换操作.sub 和 sub ...
- input标签让光标不出现
<input class="red" readonly unselectable="on" > input点击变为搜索框,用form包住绑定搜索事 ...
- Codeforces Round #267 (Div. 2) D. Fedor and Essay tarjan缩点
D. Fedor and Essay time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- zipkin启动报错(Caused by: java.lang.ClassNotFoundException: zipkin.Component)的解决方法
使用ziplin依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifact ...
- idea输出目录详解
引言:在项目中遇到了一个问题,在使用idea时,项目中Tomcat的虚拟目录映射总是失败,而当我采用myeclipse时却能映射过去. 自己花费了很长时间,终于找出了问题所在,原来是由于idea自己采 ...
- [转]VS中的路径宏 OutDir、ProjectDir、SolutionDir各种路径含义
转自 http://blog.csdn.net/restraint/article/details/39934401 说明 $(RemoteMachine) 设置为“调试”属性页上“远程计算机”属性的 ...
- Eclipse添加EGIT方法
1. 安装EGIT, 其中一个方法: 2. 新建javaweb项目,测试git的使用. l File > Team > Share Project 选择GIT 如何选择不了,则选择创建c ...
- 【Linux】人脸识别的封装
写了一个linux下的Face Recognition的封装,当作是练习.语言: C++的封装,结合opencv,使用方便.下载源码:https://github.com/zacario-li/Fac ...
- Python 读写操作Excel —— 安装第三方库(xlrd、xlwt、xlutils、openpyxl)
数据处理是 Python 的一大应用场景,而 Excel 则是最流行的数据处理软件.因此用 Python 进行数据相关的工作时,难免要和 Excel 打交道. 如果仅仅是要以表单形式保存数据,可以借助 ...