【Spring】初识 Spring AOP(面向切面编程)
目录
1、介绍AOP
1.1、AOP的定义
1.2、AOP的作用
1.3、AOP的核心概念及术语
2、AOP实现示例
3、@EnableAspectJAutoProxy注解

1、介绍AOP
1.1、AOP的定义
AOP(Aspect Orient Programming),直译过来就是面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。AOP可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,比如Spring的事务,通过事务的注解配置,Spring会自动在业务方法中开启、提交业务,并且在业务处理失败时,执行相应的回滚策略。
1.2、AOP的作用
作用:AOP 采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。
主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
简单的说,AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。
AOP的经典应用场景有:日志记录、事务管理、权限验证、性能监测
AOP可以拦截指定的方法,并且对方法增强,比如:事务、日志、权限、性能监测等增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离。
1.3、AOP的核心概念及术语
目标对象(Target):目标对象指将要被增强(比如增强功能)的对象,或者说被一个或多个切面所通知的对象,即包含主业务逻辑的类的对象,即为目标对象。
可以说要增强的对象(通常会有很多个)就是目标对象
切面(Aspect):指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schema-basedapproach)或者在普通类中以@Aspect注解(@Aspect注解方式)来实现。
可以说增强代码放入的那个类就叫切面类,由@Aspect注解来标识
通知(Advice):在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”,“before” 和“after”等等。通知的类型将在后面详细了解。许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。
用来放增强的代码的那个方法就是通知
- 环绕通知@Around:可以把代码增强在目标方法的任意地方,更通用
- 前置通知@Before:目标方法之前执行
- 后置通知@After:目标方法之后执行
- 异常通知@AfterThrowing:目标方法出现了异常执行
- 返回通知@AfterReturning:目标方法返回值执行
切点(Pointcut):匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用Aspectj切点语义。
增强代码要对哪些类中的哪些方法进行增强,进行切割,指的是被增强的方法,即要切哪些东西。切点表达式
连接点(Join point):在Spring AOP中,一个连接点总是代表一个方法的执行,其实就代表增强的方法。
连接点就是通知和目标方法的一个桥梁,可以获取到目标方法的信息,就得通过JoinPoint
顾问(Advisor):顾问是Advice的一种包装体现,Advisor是Pointcut以及Advice的一个结合,用来管理Advice和Pointcut。应用无需关心.
顾问是源码中的体现,会封装切点和通知
织入(Weaving):将通知切入连接点的过程叫织入,就是我这个增强代码织入到目标方法或者叫切入到目标方法都可以
2、AOP实现示例
假设有一个类的所有业务功能都已经实现,但是最后我想在所有的功能里面加一个公共的功能(记录所有的请求的用时), 这时候就可以利用AOP来实现,切面就是(需要增强的公共的、跟业务没有关系的公共代码)。可以在不改变原有业务代码的基础上进行了增强。所以面向切面编程往往让我们的开发更加低耦合,也大大减少了代码量,同时呢让我们更专注于业务模块的开发,把那些与业务无关的东西提取出去,便于后期的维护和迭代。
如何在Spring中创建一个所谓切面?
切面里面的代码怎么运行在业务方法(运行在之前、运行在之后)
使用AOP需要引入依赖
<!--以spring-boot-starter为前缀的依赖都是springboot官方提供的依赖,
不需要自己来指定版本,因为parent都帮我们管理好了,
springboot通过这种方式统一管理了版本,可以减少版本的冲突-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

aspectj:AOP概念并不是spring独家提出来的,AOP早就有成熟框架已经实现了,aspectj就是一个成熟的AOP的解决方案,spring只不过是把aspectj集成进来了
AOP实现示例代码:@Aspect注解可以把一个类标记为切面类
自定义类UserService,假设其所有业务功能(增删查改)都已经实现,但是我想给这些功能加一个记录请求用时的功能。这时用AOP来实现
//自定义类UserService,假设其所有业务功能都已经实现
@Service
public class UserService {// 增加增删改查方法,这里就用一个打印语句来代替具体的方法功能了public void add(){System.out.println("增加");}public void delete(){System.out.println("删除");}public void update(){System.out.println("修改");}public void query(){System.out.println("查询");}
}//切面类LogAspect,通过这个切面类来实现在所有的功能里面加一个公共的功能(记录所有的请求的用时)
@Aspect //把这个类标记为切面类
@Component //切面类必须声明为Spring的bean
public class LogAspect, {// execution(* com.lt.UserService.*(..)) 切点表达式// @Around 环绕通知@Around("execution(* com.lt.UserService.*(..))") //切点表达式public void log(ProceedingJoinPoint proceedingJoinPoint){//记录方法用时long begin = System.currentTimeMillis();// 执行具体的方法try {proceedingJoinPoint.proceed();} catch (Throwable e){System.out.println("方法执行异常:" + e.getMessage());}long end = System.currentTimeMillis();System.out.println("方法用时:" + (end - begin) + "ms");}}//测试类C4AopApplicationTests
@SpringBootTest(classes = C4AopApplicationTests.class)
@ComponentScan
class C4AopApplicationTests {@Testvoid contextLoads(@Autowired UserService userService) {userService.add();}}
运行结果:

3、@EnableAspectJAutoProxy注解
1、@EnableAspectJAutoProxy:启用AOP,没有这个注解AOP功能无法使用
如果要使用SpringAOP的功能,必须要添加一个@EnableAspectJAutoProxy注解,有了这个注解才能支持@Aspect等相关的一系列AOP注解的功能,这个注解就相当于在传统的xml配置文件中添加 <aop:aspectj-autoproxy>一样。
2、@EnableAspectAutoProxy不是一定要加的
比如上面的AOP示例,为什么没有加@EnableAspectJAutoProxy注解,AOP也起作用了?
这是因为SpringBoot其实会通过启动类自动帮我们加上@EnableAspectJAutoProxy,所以可以省略。(@SpringBootApplication这个注解帮我们做了很多的事情,包括自动帮我们加上@EnableAspectJAutoProxy注解)
//测试类C4AopApplicationTests
@SpringBootTest(classes = C4AopApplicationTests.class)
@ComponentScan
class C4AopApplicationTests {......
}//启动类
@SpringBootApplication // 由于这个注解起了作用,所以自动加了@EnableAspectJAutoProxy
public class C4AopApplication {......
}

所以com.lt包下的启动类C4AopApplication和他上面的上面的注解@SpringBootApplicatio也会被扫描到,由于这个注解起了作用,所以自动加了@EnableAspectJAutoProxy
但是依然建议加上@EnableAspectJAutoProxy,因为在Spring中没有这个注解AOP功能会无法使用。

推荐:
【Spring】IOC/DI中常用的注解@Lazy、@Scope与@Conditional-CSDN博客
https://blog.csdn.net/m0_65277261/article/details/138277932?spm=1001.2014.3001.5501
【Spring】IOC/DI中常用的注解@Order与@DependsOn-CSDN博客
https://blog.csdn.net/m0_65277261/article/details/138167160?spm=1001.2014.3001.5501
【spring】Bean的生命周期回调函数和Bean的循环依赖-CSDN博客
https://blog.csdn.net/m0_65277261/article/details/138503989?spm=1001.2014.3001.5501
相关文章:
【Spring】初识 Spring AOP(面向切面编程)
目录 1、介绍AOP 1.1、AOP的定义 1.2、AOP的作用 1.3、AOP的核心概念及术语 2、AOP实现示例 3、EnableAspectJAutoProxy注解 1、介绍AOP 1.1、AOP的定义 AOP(Aspect Orient Programming),直译过来就是面向切面编程,AOP 是一…...
k8s各个组件的作用
Kubernetes(K8s)是一个开源的容器编排平台,用于自动化计算机容器化应用程序的部署、扩展和管理。以下是 Kubernetes 中的关键组件及其作用: API 服务器(API Server): 作为集群中所有资源操作的入…...
Spring Cloud 整合Sentinel
1、引入依赖 版本说明 alibaba/spring-cloud-alibaba Wiki GitHub 父pom <spring.cloud.version>Hoxton.SR12</spring.cloud.version> <spring.cloud.alibaba.version>2.2.10-RC1</spring.cloud.alibaba.version>Sentinel应用直接引用starter <…...
Java入门基础学习笔记4——开发Helloworld入门程序
Java程序开发的三个步骤: 1)编写代码 2)编译代码 3)运行代码 注意事项: 第一个java程序建议使用记事本来编写。 建议代码文件名全英文、首字母大写、满足驼峰模式,源代码文件的后缀必须是.java 注意&a…...
了解WebSocket
1.概念: WebSocket是一种在单个TCP连接上进行全双工通信的协议,属于应用层协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握…...
从开发角度理解漏洞成因(02)
文章目录 文件上传类需求文件上传漏洞 文件下载类需求文件下载漏洞 扩展 留言板类(XSS漏洞)需求XSS漏洞 登录类需求cookie伪造漏洞万能密码登录 持续更新中… 文章中代码资源已上传资源,如需要打包好的请点击PHP开发漏洞环境(SQL注…...
Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点
文章目录 一、通信机制1、轮询1.1、短轮询1.2、长轮询 2、Websocket3、Server-Sent Events 二、区别1、连接方式2、协议3、兼容性4、安全性5、优缺点5.1、WebSocket 的优点:5.2、WebSocket 的缺点:5.3、SSE 的优点:5.4、SSE 的缺点࿱…...
TMS320F280049 CLB模块--LUT4 OUTLUT(4)
LUT4 示意图如下: OUTLUT 示意图如下: 寄存器 参考文档: TMS320F28004x Real-Time Microcontrollers Technical Reference Manual (Rev. G)...
功能测试_分类_用例_方法
总结 测试分类 按阶段分类 是否查看源代码分类 是否运行分类 是否自动化 其他分类 软件质量模型 开发模型-瀑布模型 测试过程模型 v w 测试用例八大要素 用例编号 用例标题 …...
[沫忘录]MySQL 锁
[沫忘录]MySQL 锁 锁能够协调多线程或多进程并发访问某资源产生的数据冲突与错乱。而在数据库中,锁也是协调数据库访问的有效工具。 全局锁 能够锁住当前服务器所有数据库及其表。后续所有事务都只能进行读操作,而不能进行写操作或表属性更改。 典型…...
噪声嵌入提升语言模型微调性能
在自然语言处理(NLP)的快速发展中,大模型(LLMs)的微调技术一直是研究的热点。最近,一篇名为《NEFTUNE: NOISY EMBEDDINGS IMPROVE INSTRUCTION FINETUNING》的论文提出了一种新颖的方法,通过在训…...
XML文档基本语法
XML文档基本语法包括以下几个知识点: 开始标记(Start Tag):开始标记是XML元素的起始符号,由左尖括号(<)和元素名称组成。例如,是一个开始标记,表示一个名为"book…...
git开发工作流程
git开发工作流程 (1)先将远程代码pull到本地 (2)在本地上分支上进行开发 (3)开发完之后,push到远程分支 (4)由远程的master进行所有分支合并...
JDK生成https配置
keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:\https证书\weChat.keystore -validity 36500 -keypass 250250 keytool -importkeystore -srcstoretype JKS -srckeystore D:\https证书\weChat.keystore -srcstorepass 250250 -srcalias tomcat -srckeypass 25025…...
通过 Java 操作 redis -- set 集合基本命令
目录 使用命令 sadd ,smembers 使用命令 sismember 使用命令 scard 使用命令 spop 使用命令 sinter,sinterstore,sunion,sunionstore,sdiff,sdiffstore 关于 redis set 集合类型的相关命令推荐看Redis …...
WebSocket前后端建立以及使用
1、什么是WebSocket WebSocket 是一种在 Web 应用程序中实现双向通信的协议。它提供了一种持久化的连接,允许服务器主动向客户端推送数据,同时也允许客户端向服务器发送数据,实现了实时的双向通信。 这部分直接说你可能听不懂;我…...
C++数据结构之链表树图的存储
本文主要介绍用数组存储,结构只做简单介绍 目录 文章目录 前言 结构体实现 1、链表的存储 2、树的存储 3、图的存储 数组实现 1、链表实现 2、树和图的实现 总结 前言 在正常工程中,我们通常使用结构体或者类,来定义并使用如链表…...
又一位互联网大佬转行当网红,能写进简历么?
最近半个月,有两个中年男人仿佛住进了热搜。 一个是刚刚辟谣自己“卡里没有冰冷的 40 亿”的雷军,另一个则是在今年年初就高呼“如果有可能,企业家都要去当网红”的 360 创始人周鸿祎。 他也确实做到了。 先是作为当年 3Q 大战的当事人&…...
Codeforces Round 134 (Div. 1) A. Ice Skating (并查集)
Ice Skating 题面翻译 Description 给出n个点的横纵坐标,两个点互通当且仅当两个点有相同的横坐标或纵坐标,问最少需要加几个点才能使得所有点都两两互通 Input 第一行一个整数n表示点数,之后n行每行两个整数x[ i ]和y[ i ]表示第i个点的…...
深入了解 Flask Request
文章目录 获取请求数据获取请求信息文件上传总结 Flask 是一个轻量级的 Python Web 框架,其简洁的设计和灵活的扩展性使其成为了许多开发者的首选。在 Flask 中,处理 HTTP 请求是至关重要的,而 Flask 提供了丰富而强大的 request 对象来处理…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
