SpringBoot通过3种方式实现AOP切面

news2024/11/15 20:37:05
❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基

文章目录

      • 前言
      • 1. 使用动态代理实现AOP
      • 2. 使用Java Agent技术实现AOP(AspectJ Weaver)
      • 3. 使用AspectJ编译时织入实现AOP
      • 总结

前言

Spring,SpringBoot框架凭借多种高效机制,显著增强了代码的功能性,并实现了切面编程(AOP)的精髓。其核心亮点之一,是运用动态代理技术,无需触动源代码即可在Bean的运行时为其动态织入额外功能,如日志记录、安全验证等,从而实现非侵入式的代码增强。

此外,Java Agent技术,以AspectJ Weaver为代表,在JVM层面上大显身手,拦截类加载过程并动态修改类字节码。这一技术不仅拓展了AOP的应用场景,还蕴含了巨大的性能优化潜力,为开发者提供了更多元化的AOP实现方式。

AspectJ-Maven-Plugin编译插件则采取了另辟蹊径的方法。它在编译阶段直接对源代码或字节码进行修改,确保切面逻辑与业务代码的无缝融合。这种方式不仅优化了程序的性能,还大幅减少了运行时的开销,为复杂的业务逻辑提供了坚实的支撑。

1. 使用动态代理实现AOP

定义:AOP是一种编程范式,用于将横切关注点(如日志、安全、事务管理等)从业务逻辑中分离出来,形成独立的模块。这样可以减少代码的冗余,提高代码的可维护性和模块性。

特点

  • 关注点分离:将横切关注点与业务逻辑分离。
  • 提高代码复用:横切关注点可以被多个地方复用。
  • 减少代码冗余:避免了在多个地方重复编写相同的代码。

通过动态代理方式,只需要在项目中定义@Aspect切面即可完成增强逻辑,利用CGLIB生成了代理类。

切面类代码

@Aspect
@Component
public class LoggingAspect {

    // 定义切点
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayerExecution(){}

    // 在切点方法执行前执行
    @Before("serviceLayerExecution()")
    public void logBeforeServiceMethod(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }

    // 可以继续添加其他类型的通知,如@After、@AfterReturning、@AfterThrowing、@Around等
}

服务类代码

@Service
public class UserService {
    public void save() {
        System.out.println("Saving user...");
    }
}

2. 使用Java Agent技术实现AOP(AspectJ Weaver)

定义:Java Agent技术允许开发者在JVM层面拦截类加载过程,动态修改类字节码。这种技术通过Java Instrumentation API实现。

应用场景

  • AOP支持:利用Java Agent技术(如AspectJ Weaver),可以在JVM层面拦截类加载过程,动态修改类字节码,实现更广泛的AOP支持。
  • 性能优化:通过动态修改字节码,可以优化类的执行性能。
  • 动态监控与调试:在类加载时注入监控或调试代码。

特点

  • 广泛支持:支持在JVM层面进行类加载的拦截和修改。
  • 配置复杂:相比其他AOP实现方式,配置可能更为复杂。

使用Java Agent技术涉及到更复杂的配置,包括编写自定义的Agent类,主要步骤包括将AspectJ Weaver作为Java Agent运行。下面看看aop.xml和切面类的配置。

aop.xml(放在META-INF目录下):

<aspectj>
    <weaver>
        <!-- 指定哪些包下的类需要被织入 -->
        <include within="com.example.service..*"/>
    </weaver>
    <aspects>
        <!-- 指定切面类,可定义多个 -->
        <aspect name="com.example.aspect.LoggingAspect"/>
    </aspects>
</aspectj>

切面类代码(与动态代理类似,但不需要@Component注解):

@Aspect
public class LoggingAspect {
    // 与动态代理相同的切点和通知定义
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayerExecution(){}

    @Before("serviceLayerExecution()")
    public void logBeforeServiceMethod(JoinPoint joinPoint) {
        // 日志记录逻辑
    }
}

** 指定JVM参数 **
使用Java Agent时,需要在JVM启动参数中指定AspectJ Weaver的jar包

-javaagent:d:/maven/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar

通过以上实现, 我们的SpringBoot业务代码UserService 被增强了,同时UserService并没有创建代理。通过反编译查看UserService编译后的字节码也没有任何的变化。Agent的原理就在进行类加载时对类进行增强。

3. 使用AspectJ编译时织入实现AOP

定义:AspectJ-Maven-Plugin是一个Maven编译插件,用于在编译时直接修改源代码或字节码,以集成切面逻辑。

应用场景

  • AOP集成:通过编译时修改字节码,实现切面逻辑与业务代码的无缝集成。
  • 性能优化:由于是在编译阶段进行代码的增强,因此减少了运行时的开销,提升了性能。

特点

  • 性能最佳:编译时增强减少了运行时的开销。
  • 深度集成:切面逻辑与业务代码无缝集成。
  • 需要重新编译:每当切面逻辑或业务代码发生变化时,都需要重新编译项目。

SpringBoot中,动态代理的方式,通过对目标类生成代理,在执行目标方法前执行增强逻辑Advice,这种方式多少对性能是有影响的。而编译插件方式是在编译时增强,性能最佳,深度集成,减少运行时开销。

pom.xml中添加AspectJ-Maven-Plugin

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.11</version>
    <configuration>
        <showWeaveInfo>true</showWeaveInfo>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>com.example</groupId>
                <artifactId>your-aspect-library</artifactId>
            </aspectLibrary>
        </aspectLibraries>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal> <!-- use this goal to weave all your main classes -->
                <goal>test-compile</goal> <!-- use this goal to weave all your test classes -->
            </goals>
        </execution>
    </executions>
</plugin>

注意:如果切面类位于同一项目中,不需要单独指定aspectLibraries

切面类代码(与动态代理相同,不需要@Component注解):

…省略很多代码…

…完整代码请关注博主公众号 [ 码到三十五 ] 回复 [ springboot ] 自动获取…

总结

  • AOP:是一种编程范式,用于将横切关注点从业务逻辑中分离出来,提高代码的可维护性和模块性。
  • Java Agent:在JVM层面拦截类加载过程,动态修改类字节码,支持广泛的AOP场景,但配置可能较为复杂。
  • AspectJ-Maven-Plugin:是一个Maven编译插件,通过编译时修改字节码来集成切面逻辑,性能最佳,但需要重新编译项目。

关注公众号[码到三十五]获取更多技术干货 !

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

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

相关文章

实战内测-某内测项目站点FUZZ到Sql注入

0x1 前言 下面给师傅们分享的案例呢是前段时间实战的一个站点&#xff0c;也是我朋友前段时间让我测的一个站点。整体的测试流程也还算ok&#xff0c;然后里面有些细节要是对师傅们有帮助可以收藏下&#xff0c;后面主要是利用FUZZ打了一个sql注入漏洞上去。 0x2 fuzz和sql结…

MAC安装acl

在编译前&#xff0c;需要先从 github https://github.com/acl-dev/acl 下载源码&#xff0c;国内用户可以选择从 gitee https://gitee.com/acl-dev/acl 下载源码。 3.1、Linux/Unix 平台上编译安装 在 Linux/Unix 平台上的编译非常简单&#xff0c;可以选择使用 make 方式或 …

【高校科研前沿】马里兰大学地理科学系在环境科学Top期刊发文:美国本土湿地因不透水面而损失的热点区域

1.文章简介 论文名称&#xff1a;Hotspots of wetland loss to impervious surfaces in the conterminous United States&#xff08;美国本土湿地因不透水面而损失的热点区域&#xff09; 第一作者及单位&#xff1a;Zhenhua Zou&#xff08;马里兰大学(美国)|助理研究教授&a…

Widget自定义动画按钮实战(鼠标进入则放大,离开恢复)

目录 引言 准备工作 步骤一&#xff1a;创建项目和基础控件 步骤二&#xff1a;设计UI 步骤三&#xff1a;自定义按钮类&#xff08;AniBtn&#xff09; 步骤四&#xff1a;在主窗口中使用自定义按钮 步骤五&#xff1a;编译和运行 总结 引言 在Qt开发中&#xff0c;自…

226翻转二叉树

解题思路&#xff1a; \qquad 树相关的题&#xff0c;大部分都可以通过递归来解决。因为树结构&#xff08;尤其是二叉树&#xff09;天然地具有递归发展的性质&#xff1a;对于二叉树的每个树节点&#xff0c;都有一个左节点和一个右节点&#xff0c;且能无限重复延伸。 \qqu…

World of Warcraft [retail] 100G download 2024.07.31

正式服 D:\Battle.net\World of Warcraft\_retail_

微信小程序-选中文本时选中checkbox

1.使用labe嵌套住checkbox标签 <label class"label-box"> <checkbox >匿名提交</checkbox> </label>2.使checkbox和label组件在同一行 .label-box{display: flex;align-items: center; }效果图 此时选中文本匿名提交&#xff0c;checkbox…

ft232 win10驱动

ft232 win10驱动 https://ftdichip.com/drivers/d2xx-drivers/

2024年导游资格证考试报名照很严格!

2024年导游资格证考试报名照很严格&#xff01; #导游证考试 #导游证 #导游资格证考试 #导游资格证 #全国导游证考试 #导游证报名

初学者如何快速掌握工程项目管理软件?

国内外主流的10款工程项目管理系统软件对比&#xff1a;PingCode、Worktile、金蝶EAS、用友NC、汉得信息H3 BPM、SAP ERP、Wrike、Zoho Projects、Accelo、Celoxis。 选择合适的工程项目管理系统软件往往令许多项目经理和团队感到头痛。这不仅关系到项目的效率和成功率&#xf…

C++初学(8)

8.1、string类简介 现在可以用string类型的变量而不是字符数组来存储字符串&#xff0c;string类也用的会比数组简单&#xff0c;同时提供了将字符串作为一种数据类型的表示方式。 要使用string类&#xff0c;必须在程序中包含头文件string。string类位于名称空间std中&#…

昇思25天学习打卡营第XX天|GAN图像生成

感觉顺序要调整下&#xff0c;先GAN再DCGAN再Diffusion 生成式对抗网络&#xff08;GAN&#xff09;是一种前沿的无监督学习模型&#xff0c;由Goodfellow在2014年提出。它包含生成器和判别器两个对抗组件&#xff1a;生成器负责创造逼真的假图像&#xff0c;判别器则判断图像…

多语种语音合成数据,拓宽语音大模型边界

近期&#xff0c;一个名为 ChatTTS 的文本转语音项目爆火出圈&#xff0c;在 GitHub 上已经斩获了 28 k 的 Star 量。 作为一款专门为对话场景设计的语音生成模型&#xff0c;ChatTTS 支持英文和中文两种语言。针对对话式任务进行了优化&#xff0c;实现了自然流畅的语音合成。…

PG物理复制剖析

文章目录 一、物理复制概述二、同步流复制三、pg_basebackup原理源码剖析主流程具体过程 四、主从原理基本介绍1、 WAL日志文件复制2、流复制&#xff08;Streaming Replication&#xff09; 主从原理主从间的通信walsender与walreceiver过程发生故障时的行为扩展问题 一、物理…

KylinSP3 | 一篇搞定金砖信息技术应用创新赛Docker容器集群管理

KylinSP3 | 一篇搞定金砖信息技术应用创新赛Docker容器集群管理 一、知识准备1. Docker介绍2. 四大对象2.1 镜像2.2 容器2.3 网络2.4 数据卷3. Namespace介绍3.1 PID 名字空间3.2 net名字空间3.3 ipc名字空间3.4 mnt 名字空间3.5 uts名字空间3.6 user名字空间4.Docker底层原理-…

linux离线环境下安装anaconda

文章目录 背景下载及传输安装包传输安装包到linux服务器安装anacondash执行安装命令回车接受许可修改安装路径等待解压安装包添加用户环境变量 测试anaconda重新打开终端查看虚拟环境及路径使用ipython进行测试 参考文献 背景 基于内网离linux线环境下&#xff0c;且账号无roo…

Mojo编程语言:AI开发者的未来之选——代码实战解析

1. 引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;编程语言的选择对于开发效率和性能至关重要。随着AI技术的快速发展&#xff0c;开发者们对编程语言的需求也在不断演变。在这样的背景下&#xff0c;Mojo编程语言应运而生&#xff0c;它以其独特的特性和优势&am…

尚品汇-CompletableFuture异步编排-优化商品详情页(二十五)

目录&#xff1a; &#xff08;1&#xff09;创建异步对象 &#xff08;2&#xff09;计算完成时回调方法 &#xff08;3&#xff09;线程串行化与并行化方法 &#xff08;4&#xff09;多任务组合 &#xff08;5&#xff09;优化商品详情页 &#xff08;1&#xff09;创…

开启智能开发的新纪元:探索 GPT-4o mini 模型的无限可能

引言 随着人工智能技术的飞速发展&#xff0c;大型语言模型已成为推动软件开发和创新的关键力量。OpenAI 最新发布的 GPT-4o mini 模型以其卓越的性能和极具竞争力的价格&#xff0c;为开发者社区带来了新的活力。本文将探讨 GPT-4o mini 模型的特性&#xff0c;以及它如何帮助…

python ix什么意思

Pandas库中有iloc和loc以及ix可以用来索引数据&#xff0c;抽取数据。ix是一种混合索引&#xff0c;字符型标签和整型数据索引都可以。 在pandas版本0.20.0及其以后版本中&#xff0c;ix已经不被推荐使用&#xff0c;建议采用iloc和loc实现ix。这是为什么呢&#xff1f;这是由…