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

❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,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.rhkb.cn/news/388017.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sonar-Scanner: 静态代码分析的利器

Sonar-Scanner: 静态代码分析的利器 懂得享受生活的过程&#xff0c;人生才会更有乐趣。每个人都会遇到一些陷阱&#xff0c;每个人都有过去&#xff0c;有的甚至是失败的往事。过去的错误和耻辱只能说明过去&#xff0c;真正能代表人一生的&#xff0c;是他现在和将来的作为。…

【更新2022】省级农民专业合作社数量 无缺失 2006-2022

省级农民专业合作社数量是研究中国农村经济组织和农业社会化服务的重要数据。这些数据可以用来分析不同省份农业生产组织形式的多样性及其对农民生产、技术创新和收入增长的影响。研究者可以基于这些数据&#xff0c;探讨农民专业合作社在提升农产品质量、优化农业生产结构和推…

Transformer处理文本分类实例(Pytorch)

文章目录 Transformer处理文本分类实例参考网站我们构建一个实例问题,预测AG_NEWS的文本分类AG_NEWS数据集介绍预测目标总体思路(简述)主要流程数据预处理dataset构建(不是重点)构建词表 编写处理模型执行词嵌入位置编码(PositionalEncoding)(*核心)多层Transformer模块多头自注…

Mojo数据类型详解

Mojo 中的所有值都分配有相对应的数据类型&#xff0c;大多数类型都是由结构体定义的标称的类型。这些类型是标称的&#xff08;或“命名的”&#xff09;&#xff0c;因为类型相等性是由类型的名称而不是其结构决定的。 有一些类型未定义为结构&#xff0c;例如下面的两种情况…

百款精选的HTML5小游戏源码,你可以下载并直接运行在你的小程序或者自己的网站上

今天我带来了一份特别的礼物——百款精选的HTML5小游戏源码&#xff0c;你可以下载并直接运行在你的小程序或者自己的网站上&#xff0c;只需双击index.html即可开始。无论你是在寻找创意引流&#xff0c;还是想为你的网站增添互动性&#xff0c;这些小游戏都能帮你实现&#x…

办公必备!一键把PDF转换为PPT文件,只需这3款神器!

在当今数字化办公环境中&#xff0c;文件格式的转换已成为提高工作效率的关键因素之一。其中&#xff0c;PDF(便携式文档格式)和PPT(PowerPoint演示文稿)是两种广泛使用的文件格式。然而&#xff0c;有时我们需要将PDF文件转换为PPT格式&#xff0c;以便进行编辑或演示。 为方…

数据结构的基本概念与算法

数据结构的基本概念与算法 什么是数据&#xff1f; 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合&#xff1b;总结来说 -> 数据就是计算机程序加工的原料&#xff1b; 数据元素、数据项&#xf…

<数据集>棉花识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;13765张 标注数量(xml文件个数)&#xff1a;13765 标注数量(txt文件个数)&#xff1a;13765 标注类别数&#xff1a;4 标注类别名称&#xff1a;[Partially opened, Fully opened boll, Defected boll, Flower] 序…

Java面试——Tomcat

优质博文&#xff1a;IT_BLOG_CN 一、Tomcat 顶层架构 Tomcat中最顶层的容器是Server&#xff0c;代表着整个服务器&#xff0c;从上图中可以看出&#xff0c;一个Server可以包含至少一个Service&#xff0c;用于具体提供服务。Service主要包含两个部分&#xff1a;Connector和…

SQL labs-SQL注入(七,sqlmap对于post传参方式的注入,2)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。参考&#xff1a;SQL注入之Header注入_sqlmap header注入-CSDN博客 序言&#xff1a; 本文主要讲解基于SQL labs靶场&#xff0c;sqlmap工具进行的post传参方式的SQL注入&#xff0c…

【Java版数据结构】初识泛型

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;Java版数据结构 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1…

【全国大学生电子设计竞赛】2024年E题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

快速查找WGS1984 坐标地理坐标系转UTM投影坐标的多种方法

在arcgis中如果是要计算长度或面积&#xff0c;则需要将矢量图层地理坐标系转为投影坐标系&#xff0c;下面总结了几种快速找到“WGS 1984”&#xff08;UTM ZONE&#xff09;投影带号的方法。 一、准备工作 软件&#xff1a;arcmap 示例数据&#xff1a;安微省shp矢量图 二…

删除链表的倒数第N个结点(LeetCode)

题目 给你一个链表&#xff0c;删除链表的倒数第个结点&#xff0c;并且返回链表的头结点。 示例1&#xff1a; 输入&#xff1a;&#xff0c; 输出&#xff1a; 示例2&#xff1a; 输入&#xff1a;&#xff0c; 输出&#xff1a; 示例3&#xff1a; 输入&#xff1a;&#x…

申瓯通信设备有限公司在线录音管理系统(复现过程)

漏洞简介 申瓯通信设备有限公司在线录音管理系统 index.php接口处存在任意文件读取漏洞&#xff0c;恶意攻击者可能利用该漏洞读取服务器上的敏感文件&#xff0c;例如客户记录、财务数据或源代码&#xff0c;导致数据泄露 一.复现过程 fofa搜索语句:title"在线录音管…

【Vue3】标签的 ref 属性

【Vue3】标签的 ref 属性 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。…

Ubuntu22.04手动安装fabric release-2.5版本

这个过程稍微有点复杂&#xff0c;但完整操作完成以后会对Fabric网络有更加深入的理解&#xff0c;方便后续自己手动搭建Fabric网络。这个过程需要手动逐个下载Fabric源代码、使用命令下载Fabric镜像和用Git下载例子程序。 Fabric源代码主要用途是用来编译cryptogen、configtx…

二叉搜索树(图解)

文章目录 二叉搜索树的概念插入查找二叉搜索树的删除操作删除单孩子和叶子节点。del节点有两个孩子用左子树的最大节点替代用右子树的最小节点替代 弊端 二叉搜索树的概念 对于每颗子树&#xff0c;左子树 < 根&#xff0c;右子树 > 根。 二叉搜索树有以下操作&#xff1…

代码随想录二刷(哈希表)

代码随想录二刷(哈希表) 三数之和思路反正对于我来说是真的难想出来。 若这道题还是采用哈希表的思路去做&#xff0c;非常麻烦&#xff0c;并且还要考虑去重的操作。所以这道题其实用双指针&#xff0c;是更方便的。 具体程序如下&#xff1a; class Solution:def threeSu…

Docker简介和Docker常见命令

目录 1. Docker 简介 1.1 Docker 的核心概念 1.2 Docker 的优势 1.3 Docker 工作流程 2. 常见命令 2.1 基本命令 2.2 镜像操作 2.3 容器操作 2.4 网络操作 2.5 卷操作 2.6 日志和监控 2.7 清理命令 3. 注意事项和最佳实践 3.1 镜像操作 3.2 容器操作 3.3 网络操…