Spring AOP —— 详解、实现原理、简单demo
目录
一、Spring AOP 是什么?
二、学习AOP 有什么作用?
三、AOP 的组成
3.1、切面(Aspect)
3.2、切点(Pointcut)
3.3、通知(Advice)
3.4、连接点
四、实现 Spring AOP 一个简单demo
4.1、添加 Spring AOP 框架依赖
4.2、定义切面
4.3、定义切点
4.3.1、切点表达式说明
4.4、定义通知
4.5、实现原理
编辑
五、Spring AOP 实现原理
5.1、原理概述
5.2、织入
5.3、动态代理
5.4、面试题:DK 和 CGLIB 实现的区别
一、Spring AOP 是什么?
AOP 就是面向切面的编程, 是一种思想,是对某一类事情的集中处理。
例如登陆权限的检验(检测当前用户是否登录),在学习 AOP 前,我们会将这样一个检测机制封装成一个方法,在需要检测的地方调用该方法即可,但想象以下,首先,如果这个方法有 1000 个地方要进行调用, 那么你去一个一个写调用函数很累,其次,一旦这个登陆检查方法需要修改,比如增加一个参数,那么,你就需要修改 1000 方法调用的参数... 但如果你会 AOP 后,我们只需要在某处配置一下,就可以实现用户的登录检测,不需要每一个方法中都写登录检验的调用方法啦!
AOP 是一种思想,而 Spring AOP 是一个框架,提供了对 AOP 思想的实现(类似于 IoC 和 DI 的关系)。
二、学习AOP 有什么作用?
例如刚刚我们所讲到的登录检测机制,这一个方法一旦需要调用的地方多了,不仅写起来麻烦,维护起来成本也是很高的,所以,对于这种功能统一,且使用地方较多的功能,就可以考虑 AOP 来进行统一的处理!
例如以下常见的使用场景:
- 统一登录检测机制。
- 统一方法的执行时间统计。
- 统一的返回格式设置。
- 统一异常处理。
- 事务的开始和提交。
Ps: AOP 是对某一功能进行的统一处理,大大降低了代码维护的成本,所以可以说 AOP 是 OOP 的补充和完善~
三、AOP 的组成
3.1、切面(Aspect)
切面,在程序中就是对某一功能进行统一处理的类, 这个类里包含了很多方法,这些方法就是由 切点 和 通知 组成。
3.2、切点(Pointcut)
用来进行主动拦截的规则(配置)。
这里拦截的是什么,过程是什么样的呢?就是对用户向服务器发送的请求进行拦截,检测用户的操作是否符合预期,发现问题并统一处理的过程,如下图:
3.3、通知(Advice)
通知就是 AOP 的具体执行动作。具体的,在程序中被拦截后会触发一个具体的动作,就是通知中具体实现的业务代码。
在 Spring 中,可以在方法上使用以注解,设置方法为通知方法,被拦截后满足条件就会调用通知方法:
- 前置通知(@Before):执行 目标方法(被拦截的方法)之前执行的方法。
- 后置通知(@After):执行了目标方法之后执行的方法。
- 返回之后通知(@AfterReturning):目标方法执行了返回数据(return)时,执行的方法。
- 抛异常后通知(@AfterThrowing):在执行目标方法出现异常时,执行的方法。
- 环绕通知(@Around):在目标方法执行的周期范围内(执行之前,执行中,执行后)都可以执行的方法(Ps:如果已经有了前置和后置通知,再使用环绕通知,那么周期范围就在前置通知之前 ~ 后置通知之后)。
3.4、连接点
会触发 AOP 规则的所有的点(所以请求)。
四、实现 Spring AOP 一个简单demo
4.1、添加 Spring AOP 框架依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
Ps:
1.创建 Spring Boot 项目时是没有 Spring AOP 框架可以选择的。
2.添加 Spring AOP 框架可以去中央仓库,值得注意的是要选择 Spring Boot 对应的 AOP ,而不是 Spring 对应的 AOP。
3.最好选择 Spring Boot 对应版本的 AOP ,以上就是 2.7.9版本。
4.2、定义切面
使用 @Aspect 注解修饰类,告诉框架是一个切面类。
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;@Aspect //告诉框架我是一个切面类
@Component
public class UserAspect {}
4.3、定义切点
使用 @Pointcut 修饰一个方法,它不需要由方法体。方法名就是起到一个标识的作用,标识通知方法具体指的是哪一个切点(切点可能有多个)。
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Aspect //告诉框架我是一个切面类
@Component
public class UserAspect {/*** 切点:配置拦截规则*/@Pointcut("execution(* com.example.demo.controller.UserController.*(..))")public void pointcut() {}}
4.3.1、切点表达式说明
AspectJ ⽀持三种通配符,如下:
- * :匹配任意字符,只匹配⼀个元素(包,类,或⽅法,⽅法参数)
- .. :匹配任意字符,可以匹配多个元素 ,在表示类时,必须和 * 联合使⽤。
- + :表示按照类型匹配指定类的所有类,必须跟在类名后⾯,如 com.cad.Car+ ,表示继承该类的 所有⼦类包括本身
切点表达式由切点函数组成,其中 execution() 是最常⽤的切点函数,⽤来匹配⽅法,语法如下(注意使用空格进行分割):
execution(<修饰符> <返回类型> <包.类.⽅法(参数)> <异常>)
其中,修饰符和异常可以省略,具体含义如下:
4.4、定义通知
使用通知方法中的五个注解,其中前置通知、后置通知、环绕通知最常用,那么以下代码我将用这三个注解来举例:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Aspect //告诉框架我是一个切面类
@Component
public class UserAspect {/*** 切点:配置拦截规则*/@Pointcut("execution(* com.example.demo.controller.UserController.*(..))")public void pointcut() {}/*** 前置通知*/@Before("pointcut()")public void beforeAdvice() {System.out.println("执行了前置通知");}/*** 后置通知*/@After("pointcut()")public void aftereAdvice() {System.out.println("执行了后置通知");}/*** 环绕通知* @param joinPoint* @return* @throws Throwable*/@Around("pointcut()")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("进入了环绕通知~");Object obj = null;obj = joinPoint.proceed();System.out.println("退出了环绕通知~");return obj;}}
执行结果如下:
4.5、实现原理
五、Spring AOP 实现原理
5.1、原理概述
Spring 的切面是代理类实现的,包裹了目标对象,也就是说,用户只能先通过代理类,进行校验,如果没有问题才会进一步访问到目标对象。
5.2、织入
织入简单理解就是代理生成的时机,一般情况下,在 Spring AOP 动态代理的植入时机是程序的运行期。
5.3、动态代理
Spring AOP 是建立在动态代理的基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截。
Spring AOP 支持 JDK Proxy 和 CGLIB 方式实现动态代理。默认情况下,实现了接口的类,使用 AOP 会基于 JDK 生成代理类,没有实现接口的类,会基于 CGLIB 生成代理类。
JDK 和 CGLIB 底层都是基于反射实现的。、
5.4、面试题:DK 和 CGLIB 实现的区别
1. JDK 实现,要求被代理类必须实现接⼝,之后是通过 InvocationHandler 及 Proxy,在运⾏ 时动态的在内存中⽣成了代理类对象,该代理对象是通过实现同样的接⼝实现(类似静态代理接⼝实现的⽅式),只是该代理类是在运⾏期时,动态的织⼊统⼀的业务逻辑字节码来完成。
2. CGLIB 实现,被代理类可以不实现接⼝,是通过继承被代理类,在运⾏时动态的⽣成代理类对象。
相关文章:

Spring AOP —— 详解、实现原理、简单demo
目录 一、Spring AOP 是什么? 二、学习AOP 有什么作用? 三、AOP 的组成 3.1、切面(Aspect) 3.2、切点(Pointcut) 3.3、通知(Advice) 3.4、连接点 四、实现 Spring AOP 一个简…...

(蓝桥真题)异或数列(博弈)
题目链接:P8743 [蓝桥杯 2021 省 A] 异或数列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 样例输入: 4 1 1 1 0 2 2 1 7 992438 1006399 781139 985280 4729 872779 563580 样例输出: 1 0 1 1 分析:容易想到对于异或最大值…...

4万字数字政府建设总体规划方案WORD
本资料来源公开网络,仅供个人学习,请勿商用。部分资料内容: 我省“数字政府”架构 (一) 总体架构。 “数字政府”总体架构包括管理架构、业务架构、技术架构。其中,管理架构体现“管运分离”的建设运营模式…...
CCF/CSP 201709-2公共钥匙盒100分
试题编号:201709-2试题名称:公共钥匙盒时间限制:1.0s内存限制:256.0MB问题描述:问题描述 有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥…...
【OC】Blocks模式
1. Block语法 Block语法完整形式如下: ^void (int event) {printf("buttonId:%d event%d\n", i, event); }完整形式的Block语法与一般的C语言函数定义相比,仅有两点不同。 没有函数名。带有“^”(插入记号)。 因为O…...

软件设计师教程(七)计算机系统知识-操作系统知识
软件设计师教程 软件设计师教程(一)计算机系统知识-计算机系统基础知识 软件设计师教程(二)计算机系统知识-计算机体系结构 软件设计师教程(三)计算机系统知识-计算机体系结构 软件设计师教程(…...

蓝桥杯2023/3/2
1. 小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最…...

【IoT】创业成功不可或缺的两个因素:能力和趋势
今天就来谈谈能力和趋势究竟哪个更重要的问题。 在谈成功的十大要素时,我曾经讲到: 一命、二运、三风水,这三个要素几乎不涉及任何个人的努力。 而趋势跟这三个要素又是息息相关的,这也类似雷军所说的飞猪理论。 只要风足够大&…...

2020蓝桥杯真题日期格式 C语言/C++
问题描述 小蓝要处理非常多的数据, 其中有一些数据是日期。 在小蓝处理的日期中有两种常用的形式: 英文形式和数字形式。 英文形式采用每个月的英文的前三个宁母作为月份标识, 后面跟两位数字 表示日期, 月份标识第一个字母大写, 后两个字母小写, 日期小于 10 时要补 前导 0s…...

总时差与自由时差
定义总时差(总浮动时间)(TF,Total Free Time,不耽误项目总进度)LS(Latest Start)-ES(Earliest Start)LF(Latest Finish)-EF࿰…...
LeetCode两个数组的交集-跳跃游戏- 最长有效括号
两个数组的交集 给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2] 示例 2: 输入&…...
mysql普通索引与唯一索引怎么选择
学习mysql普通索引与唯一索引选择记录总结,学习链接:http://gk.link/a/11YG8从mysql查询操作分析:普通索引:查到满足条件的第一条记录后,还会继续查找下一条记录,直到出现满足条件的记录出现后停止检索唯一…...

JavaWeb开发(三)3.5——Java的反射机制
一、反射机制的概念 指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法。这种动态获取信息,及动态调用对象方法的功能叫java语言的反射机制。 Java反射机制的核心是在程序运行时动…...

Python每日一练(20230305)
目录 1. 正则表达式匹配 ★★★ 2. 寻找旋转排序数组中的最小值 II ★★★ 3. 删除排序链表中的重复元素 II ★★ 1. 正则表达式匹配 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个…...

SpringBoot三种方法实现定时发送邮件的案例
前言 小编我将用CSDN记录软件开发之路上所学的心得与知识,有兴趣的小伙伴可以关注一下!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习,让我们共…...

opengl、opengl es、webgl介绍与opengl开发入门
1、OpenGL OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。OpenGL的高效实现(利用了图形加速硬件)存在于Windo…...

Vue3之组件间传值
何为组件间传值 在Vue3之组件文章中,我们学会了定义使用组件,但是我们似乎还缺少什么将组件之间联系起来,说到组件之间的联系就不得不提组件间的传值,而组件间的传值其实也不难理解,就是如何在子组件中接收到父组件传…...

Windows10下使用CMake编译ITK5.2.1步骤
编译环境:Windows10VS2017Cmak3.24.0ITK5.2.1 编译步骤: 1、下载ITK到本地:ITK官网Download | ITK,ITK5.2.1下载地址 https://github.com/InsightSoftwareConsortium/ITK/releases/download/v5.2.1/InsightToolkit-5.2.1.zip …...

字符串模式匹配,经典KMP算法你还不会?我可不允许你不会!
文章目录重点1. 简单模式匹配算法2. 部分匹配值PM的算法(Move j-1 PM[j-1])3. 部分匹配值PM的两次改进(Move j-next[j])4. 快速得到next数组5. KMP匹配算法重点 童鞋们看网上讲解的时候一定要分清楚序列是从0开始还是从1开始&…...
C++操作redis(实现连接池、分布式锁)
文章目录Redis连接池编译项目整体架构使用分布式锁总结Redis连接池 封装hiredis的一些基本操作,redishelper类提供包含连接,放回,存取键,push,pop,执行redis语句和执行lua脚本的函数,连接池是类…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
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 解决方案&…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...