spring-boot版本影响Spring AOP @Before @Around @After等执行顺序

news2024/11/23 23:53:25

郁闷了半天,我通过AOP切面打印的日志顺序怪怪的,网上查了好几篇文章都说没问题,最后发现是springboot版本升级后@Before @Around @After等执行顺序发生了变化。

1.切面类

@Aspect// 这是一个切面
@Component// 这是一个需要被装配的spring bean
@Slf4j
public class AopOrderAspecct {

    @Pointcut("execution(public void com.example.temp.aopOrder.*.*())")
    public void point() {
    }

    @Before("point()")
    public void before(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodName = methodSignature.getName();
        log.info("{}-执行before。。。", methodName);
    }

    @Around("point()")
    public void around(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodName = methodSignature.getName();
        log.info("{}-进入around。。。", methodName);
        try {
            joinPoint.proceed();
        } catch (Throwable throwable) {
            log.error("{}-around内部方法执行失败:{}", methodName, throwable.getMessage());
        }
        log.info("{}-around执行完毕!", methodName);
    }

    @After("point()")
    public void after(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodName = methodSignature.getName();
        log.info("{}-执行after。。。", methodName);
    }

    @AfterReturning("point()")
    public void afterReturning(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodName = methodSignature.getName();
        log.info("{}-执行afterReturning。。。", methodName);
    }

    @AfterThrowing("point()")
    public void afterThrowing(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodName = methodSignature.getName();
        log.info("{}-执行afterThrowing。。。", methodName);
    }
}

2.测试Service

@Component
@Slf4j
public class AopOrderServiceA {

    @Resource
    AopOrderServiceB serviceB;

    public void aopOrderA() {
        log.info("aopOrderA-进入方法。。。");
        int x = 0/0;
        serviceB.aopOrderB();
        log.info("aopOrderA-方法执行完毕!");
    }

}

@Component
@Slf4j
public class AopOrderServiceB {

    public void aopOrderB() {
        log.info("aopOrderB-进入方法。。。");
//        int x = 0/0;
        log.info("aopOrderB-方法执行完毕!");
    }
}

3.单元测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class OrderServiceTest {
    @Resource
    AopOrderService aopOrderService;

    @Test
    public void testOrder() {
    	String springVersion = SpringVersion.getVersion();
        String bootVersion = SpringBootVersion.getVersion();
        log.info("spring:{},springBoot:{}", springVersion, bootVersion);
        aopOrderService.aopOrder();
    }
}

4.springboot不同版本的结果

springboot版本 2.3.1.RELEASE 之前,after在around之后执行, 2.3.1.RELEASE 及之后,around包裹整个切面执行周期。

spring boot 版本为 2.0.0.RELEASE

spring:5.0.4.RELEASE,springBoot:2.0.0.RELEASE
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderA-方法执行完毕!
aopOrderA-around执行完毕!
aopOrderA-执行after。。。
aopOrderA-执行afterReturning。。。

spring boot 版本为 2.1.0.RELEASE

spring:5.1.2.RELEASE,springBoot:2.1.0.RELEASE
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderA-方法执行完毕!
aopOrderA-around执行完毕!
aopOrderA-执行after。。。
aopOrderA-执行afterReturning。。。

spring boot 版本为 2.2.0.RELEASE

spring:5.2.0.RELEASE,springBoot:2.2.0.RELEASE
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderA-方法执行完毕!
aopOrderA-around执行完毕!
aopOrderA-执行after。。。
aopOrderA-执行afterReturning。。。

spring boot 版本为 2.3.0.RELEASE

spring:5.2.6.RELEASE,springBoot:2.3.0.RELEASE
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderA-方法执行完毕!
aopOrderA-around执行完毕!
aopOrderA-执行after。。。
aopOrderA-执行afterReturning。。。

spring boot 版本为 2.3.1.RELEASE(从这里开始不一样)

spring:5.2.7.RELEASE,springBoot:2.3.1.RELEASE
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderA-方法执行完毕!
aopOrderA-执行afterReturning。。。
aopOrderA-执行after。。。
aopOrderA-around执行完毕!// 注意,这里不同

spring boot 版本为2.7.0(目标方法执行抛出异常时)

spring:5.3.20,springBoot:2.7.0
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderA-执行afterThrowing。。。// 注意,这里不同
aopOrderA-执行after。。。
aopOrderA-around内部方法执行失败:/ by zero
aopOrderA-around执行完毕!

当目标方法切面嵌套时

spring:5.3.20,springBoot:2.7.0
aopOrderA-进入around。。。
aopOrderA-执行before。。。
aopOrderA-进入方法。。。
aopOrderB-进入around。。。
aopOrderB-执行before。。。
aopOrderB-进入方法。。。
aopOrderB-方法执行完毕!
aopOrderB-执行afterReturning。。。
aopOrderB-执行after。。。
aopOrderB-around执行完毕!
aopOrderA-方法执行完毕!
aopOrderA-执行afterReturning。。。
aopOrderA-执行after。。。
aopOrderA-around执行完毕!
aopOrderA-方法执行完毕!
aopOrderA-执行afterReturning。。。
aopOrderA-执行after。。。
aopOrderA-around执行完毕!


流程图

在这里插入图片描述


参考连接:
https://blog.csdn.net/weixin_44005802/article/details/127014570
https://blog.csdn.net/lgxzzz/article/details/100026524

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/596984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零基础如何实现 Python 自动化办公 ?

996 一直是互联网老生常谈的话题了,但抛开其他只谈工作本身,你有没有想过,下班晚、加班,有时候可能是因为自己工作比较低效? 在这给你分享一个案例: 场景是在维护日活超过 3 亿用户的微博私信平台&#x…

Linux开机rc.local不自启动执行脚本其他一些问题进行补充说明

Linux开机rc.local不自启动执行脚本其他一些问题进行补充说明 在上一篇,我们讲了Linux开机rc.local不自启动执行脚本问题的排查思路及问题解决 这一篇我们补充一些其他的问题 问题一:我怎么知道我rc.local里面的命令启动成功不成功呢,我怎…

为什么说 Java 比 C / C++ 慢?

因为C/C允许程序员做出更多选择。 选择更多,那么: 弊端:开发效率难以提高,因为有太多选择需要斟酌。 优势:执行效率可以逼近极限,因为不会有什么抽象拦住你。 举个例子吧:大家可能对Java无处不…

New bing出现“重定向”无法使用解决方法来了

我又来分享干货了!!! 因为要润色论文,又是经过几天的折腾,终于可以正常使用bing聊天了,泪目! 首先你要有VPN才能使用New bing聊天的!要求使用edge浏览器(虽然我最后用的…

电脑mp3转换器哪个好用?我来告诉你电脑mp3转换器哪个好

假如你下载了一些音乐或者录音文件,但是它们可能不是mp3格式的,而是其他格式,如wav、flac等。而有一些设备又只能播放mp3格式的音频,这时候就需要使用mp3转换器将其转换成mp3格式,以便于在各种设备上播放和分享。不过你…

RustChinaConf 2023官网上线,精彩议题早知道

随着大会日益临近,我们RustChinaConf 2023筹备委员会的工作也在有条不紊的进行中。最新的好消息来了,官网已上线,访问地址: https://rustcc.cn/2023rustchinaconf/ 从官网进去也可以报名! 大会时间地址 6.17 - 6.1…

电影《异形》标志性雕塑将分割为500个NFT出售

由佳士得前高管领导的美术平台Particle曾创造历史般售出班克西的《爱在空中》的10000件数字作品。 5 月 31 日 - Particle ,作为去中心化的艺术生态系统和Banksy 的“Love is in the Air”画作的代币商,它将让收藏者有机会购买H.R. Giger的《异形3》原创…

我发现3个国内一直能用的免费版ChatGPT 免登免注册无广告 再不赶紧保存就没啦!

🚀 个人主页 极客小俊 ✍🏻 作者简介:web开发者、设计师、技术分享博主 🐋 希望大家多多支持一下, 我们一起进步!😄 🏅 如果文章对你有帮助的话,欢迎评论 💬点赞&#x1…

Linux多Reactor多线程网络模型

多Reactor多线程网络模型是一种用于构建高性能网络应用的并发模型。它基于事件驱动的思想,通过使用多个Reactor线程和多个工作线程来处理并发的网络请求。 底层调用关系: 在多Reactor多线程网络模型中,通常会有一个主Reactor线程和多个工作线…

凌云出海 决胜万里丨华为云中企出海领袖班第五期顺利结束!

互联网大潮风起云涌,国内竞争日益激烈内卷,越来越多的互联网企业选择国际化走出去,在全球市场这个更大舞台上找寻机会。想要抓住技术红利并惠及企业全球化,成为当下众多出海从业者的共识。 为了帮助更多的CTO领袖具备更专业的国际…

【大模型】人工智能大模型在自动驾驶领域的应用

随着ChatGPT的火爆,大模型受到的关注度越来越高,大模型展现出的能力令人惊叹。 第一个问题:怎样的模型可以称之为大模型呢? 一般来说,我们认为参数量过亿的模型都可以称之为“大模型”。而在自动驾驶领域,大…

Hibernate框架【四】——基本映射——多对一和一对多映射

系列文章目录 Hibernate框架【三】——基本映射——一对一映射 基本映射——多对一和一对多映射 系列文章目录前言一、多对一映射是什么?1.案例:现在有两个实体User实体和Group,其中多个User属于一个Group,表现出多对一的关系。①…

图解LeetCode——98. 验证二叉搜索树

一、题目 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 二、示例 2.1>…

扫描出项目中未被引用的控制器接口的工具类(超级好用)

自己的项目随着不断开发迭代,越来越庞大,后台的接口也就越来越多,难免会有一些接口后来并没有使用到,但是还在代码中,权限管理的时候这部分接口是非常多余的,为了避免这个问题,本章提供了一个工…

回归测试最小化(贪心算法,帕累托支配)

回归测试最小化(贪心算法,帕累托支配) 介绍 有时我们不能只是重新运行我们的测试(例如,当我们 换界面)。 回归测试可能很昂贵: (1)一些公司通宵运行回归测试套件。 (2) 对于嵌入式系统,我们可能必须测试正在使用的软件&#xff0…

党校学员毕业自我鉴定总结样文分享

党校学员毕业自我鉴定总结样文分享1 岁月匆匆似流水,美好的研究生三年时光马上就快结束了。经过良师的悉心指导以及自己的努力奋力拚搏、自强不息,我渐渐的成为了一个能适应现代社会要求的硕士毕业生,并为做一个知识型的社会主义建设者打下坚…

Web应用技术(第十四周/END)

本次练习基于how2j和课本,初步认识Spring。 以后我每周只写一篇Web的博客,所有的作业内容会在这篇博客中持续更新。。。 一、Spring基础1.Spring概述:2.Sring组成:3.BeanFactory:4.控制反转:5.依赖注入:6.JavaBean与S…

oracle数据库sequence的作用

sequence概念及作用 sequence是用来在多用户环境下产生唯一整数的数据库对象。序列产生器顺序生成数字,它可用于自动生成主键值,并能协调多行或者多表的主键操 作。没有sequence,顺序的值只能靠编写程序来生成。先找出最近产生的值然后自增长…

零基础初学前端—新建项目

对于一个没有基础的新手来说,如何使用 vscode 新建一个前端项目,写一些html页面,并能进行运行。 需要吐下几个步骤: 新建一个文件夹在文件夹里新建一个文件,命名为 xxx.html ,例如 index.html打开 vscode …

前端:使用rollup的简单记录

目录 rollup安装 简单使用 1、命令行打包 2、配置文件打包 问题 1、报错提示:(node:23744) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.(Use node --trace-warnings ... to sho…