aop 执行顺序
配置AOP执行顺序的三种方式:
-
通过实现org.springframework.core.Ordered接口
[java]
-
@Component
-
@Aspect
-
@Slf4j
-
-
public int getOrder() {
-
// TODO Auto-generated method stub
-
return 2;
-
}
-
-
}
-
-
通过注解
[java]
-
@Component
-
@Aspect
-
@Slf4j
-
@Order(1)
-
public class MessageQueueAopAspect1{
-
-
...
-
}
-
-
通过配置文件配置
[html]
-
<**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>**
-
我们在同一个方法上加以下两个
[java]
-
@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;
-
}
-
}
[java]
-
@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;
-
}
-
}
[java]
-
@Transactional(propagation=Propagation.REQUIRES_NEW)
-
@MessageQueueRequire1
-
@MessageQueueRequire2
-
public PnrPaymentErrCode bidLoan(String id){
-
...
-
}
看看执行结果:
从上面的测试我们看到,确实是order越小越是最先执行,但更重要的是最先执行的最后结束。
这个不难理解,
由此得出:spring aop就是一个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP1、AOP2的顺序依次执行doAround方法,doBefore方法。然后执行method方法,最后按照AOP2、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来说,先before的,一定后after。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2021-01-17 linux 创建文件夹
2021-01-17 Linux --常见Linux目录名称