【Spring Boot】Spring AOP 快速上手指南:开启面向切面编程新旅程

前言
🌟🌟本期讲解关于spring aop的入门介绍~~~
🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客
🔥 你的点赞就是小编不断更新的最大动力
🎆那么废话不多说直接开整吧~~

目录
📚️1.AOP概述
1.1什么是AOP
1.2什么是Spring AOP
📚️2.Spring AOP入门
2.1环境设置
2.2代码编写
📚️3.Spring AOP详细
3.1Spring AOP核心概念
1.切点
2.连接点
3.通知
4.切面
3.2Spring AOP通知类型
3.3@pointcut注解
3.4@order切面优先级
📚️4.总结
📚️1.AOP概述
1.1什么是AOP
AOP是Spring框架的第⼆⼤核⼼(第⼀⼤核⼼是IoC),说明AOP也是非常重要的;
AOP:Aspect Oriented Programming(⾯向切⾯编程)
面向切面编程:所谓的这里的切面就是表示一类特殊的问题,所以也叫面向特定方法编程;
这里特定的方法,在之前学习过的spring统一功能处理中,涉及到登录校验问题,而拦截器就是对这类问题的统一求解,AOP是一种求解问题的思想,那么拦截器就是一种思想的实现;
总结:
简单来说: AOP是⼀种思想, 是对某⼀类事情的集中处理
1.2什么是Spring AOP
AOP是⼀种思想, 它的实现⽅法有很多, 有Spring AOP,也有AspectJ、CGLIB等.Spring AOP是其中的⼀种实现⽅式;
在日常的代码编写中,有以下列子:

假如,我们要对这里面的接口实现改良,让执行时间减少,这里就定位到某些业务代码逻辑等改进,但是不是所有都是不好的,所以我们需要进行测试每个接口,业务执行的时间,那么就有如下的代码,来进行时间检测:

此时的方法固然是可以的,但是那么多接口都需要这样写吗??答案是不可能的,此时这就是一类特定的问题,此时我们就可以使用AOP思想来进行解决~~~
AOP就可以做到在不改动这些原始⽅法的基础上, 针对特定的⽅法进⾏功能的增强.
AOP的作⽤:在程序运⾏期间在不修改源代码的基础上对已有⽅法进⾏增强(⽆侵⼊性: 解耦)
📚️2.Spring AOP入门
2.1环境设置
首先创建一个springboot项目,设置Maven,然后引入如下的依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
这里还可以引入lombok来进行slf4j日志打印,但是在新版本中要将引入的lombok中一部分给注释掉,如下所示:
<plugins><!-- <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></path></annotationProcessorPaths></configuration></plugin>--><plugin>
2.2代码编写
具体的代码如下所示:
@Slf4j
@Aspect
@Component
//交给spring进行管理
public class TimeAspect {@Around("execution(* com.example.springaop.controller.*.*(..))")public Object timeRecord(ProceedingJoinPoint joinPoint) throws Throwable {//记录开始时间long start = System.currentTimeMillis();//执行目标方法Object proceed = joinPoint.proceed();//记录结束时间long end = System.currentTimeMillis();//日志打印耗时log.info("耗时时间: "+ (end-start) + "ms");return proceed;}
}
解释:
1. @Aspect: 标识这是⼀个切⾯类
2. @Around: 环绕通知, 在⽬标⽅法的前后都会被执⾏. 后⾯的表达式表⽰对哪些⽅法进⾏增强.
3. ProceedingJoinPoint.proceed() 让原始⽅法执⾏
那么上述代码大致分为如下:

总结优势:
• 代码⽆侵⼊: 不修改原始的业务⽅法, 就可以对原始的业务⽅法进⾏了功能的增强或者是功能的改变
• 减少了重复代码
• 提⾼开发效率
• 维护⽅便
📚️3.Spring AOP详细
3.1Spring AOP核心概念
1.切点
切点(Pointcut), 也称之为"切⼊点"
Pointcut 的作⽤就是提供⼀组规则 (使⽤ AspectJ pointcut expression language 来描述), 告诉程序对哪些⽅法来进⾏功能增强
如下所示:
execution(* com.example.springaop.controller.*.*(..))
这个就是切点表达式;
2.连接点
满⾜切点表达式规则的⽅法, 就是连接点. 也就是可以被AOP控制的⽅法,上述切点表达式中的类就是controller,说明这里面的所有方法都是AOP控制方法;

解释:直白来说就是我们需要操作的解决的一类问题接口,就是受到AOP管理的;
![]()
这个就是连接点;
3.通知
通知就是具体要做的⼯作, 指哪些重复的逻辑,也就是共性功能(最终体现为⼀个⽅法)⽐如上述程序中记录业务⽅法的耗时时间, 就是通知;
具体的部分就是如下:

在AOP⾯向切⾯编程当中, 我们把这部分重复的代码逻辑抽取出来单独定义, 这部分代码就是通知的内容.
4.切面
切⾯(Aspect) = 切点(Pointcut) + 通知(Advice)
通过切⾯就能够描述当前AOP程序需要针对于哪些⽅法, 在什么时候执⾏什么样的操作,切面包含了通知中要执行的逻辑,以及连接点的定义
3.2Spring AOP通知类型
Spring中AOP的通知类型有以下⼏种:
• @Around: 环绕通知, 此注解标注的通知⽅法在⽬标⽅法前, 后都被执⾏
• @Before: 前置通知, 此注解标注的通知⽅法在⽬标⽅法前被执⾏
• @After: 后置通知, 此注解标注的通知⽅法在⽬标⽅法后被执⾏, ⽆论是否有异常都会执⾏
• @AfterReturning: 返回后通知, 此注解标注的通知⽅法在⽬标⽅法后被执⾏, 有异常不会执⾏
• @AfterThrowing: 异常后通知, 此注解标注的通知⽅法发⽣异常后执⾏
那么这里主要是通过代码来进行实验;
每个通知类型的代码如下所示:
@Slf4j
@Component
@Aspect
public class AspectDemo1 {@Around("execution(* com.example.springaop.controller.*.*(..))")public Object aroundTest(ProceedingJoinPoint point) throws Throwable {//通知log.info("Around 开始执行");//执行目标函数Object result = point.proceed();//结束打印log.info("Around 结束执行");return result;}@Before("execution(* com.example.springaop.controller.*.*(..))")public void beforeTest(){log.info("before 开始执行");}@After("execution(* com.example.springaop.controller.*.*(..))")public void afterTest(){log.info("after 开始执行");}@AfterReturning("execution(* com.example.springaop.controller.*.*(..))")public void afterReturnTest(){log.info("afterReturn 开始执行");}@AfterThrowing("execution(* com.example.springaop.controller.*.*(..))")public void afterThrowTest(){log.info("afterThrow 开始执行");}
}
解释:
从上到下依次的通知类型,就是注解所表示,但是对于环绕通知中,要包含这里的连接点,即目标执行方法,以及返回类型是object;环绕通知需要调⽤ ProceedingJoinPoint.proceed() 来让原始⽅法执⾏, 其他通知不需要考虑⽬标⽅法执⾏;
此时运行如下的测试类:
@Slf4j
@RestController
@RequestMapping("/test")
public class AspectTest {@RequestMapping("/t1")public String test1(){log.info("这是目标方法,开始执行");return "t1";}@RequestMapping("/t2")public String test2(){log.info("这是目标方法,开始执行");int a=10/0;return "t2";}
}
那么此时我们先运行这里没有算数异常的代码,输出的情况如下所示:

解释:
程序正常运⾏的情况下, @AfterThrowing 标识的通知⽅法不会执⾏
从上图也可以看出来, @Around 标识的通知⽅法包含两部分, ⼀个"前置逻辑", ⼀个"后置逻辑".其
中"前置逻辑" 会先于 @Before 标识的通知⽅法执⾏, "后置逻辑" 会晚于 @After 标识的通知⽅法执
⾏
此时运行异常代码,结果如下所示:

解释:
@AfterReturning 标识的通知⽅法不会执⾏, @AfterThrowing 标识的通知⽅法执⾏了
• @Around 环绕通知中原始⽅法调⽤时有异常,通知中的环绕后的代码逻辑也不会在执⾏了(因为
原始⽅法调⽤出异常了
3.3@pointcut注解
上⾯代码存在⼀个问题, 就是存在⼤量重复的切点表达式 execution(* com.example.demo.controller.*.*(..)) , Spring提供了 @PointCut 注解, 把公共的切点
表达式提取出来, 需要⽤到时引⽤该切⼊点表达式即可
代码如下所示:
@Pointcut("execution(* com.example.springaop.controller.*.*(..))")public void pt(){}@Around("pt()")public Object aroundTest(ProceedingJoinPoint point) throws Throwable {//通知log.info("Around 开始执行");//执行目标函数Object result = point.proceed();//结束打印log.info("Around 结束执行");return result;}
解释:
此时就是通过@pointcut注解,对于切点表达式进行了提取,那么之后再次进行通知注解的切点表达式编写时,就可以直接使用提取的方法;
这里的方法若设置为私有类,那么只能在这一个类中进行使用,但是如果其他类要使用,这里必须变成public访问限定符;
代码如下所示:
@Slf4j
@Aspect
public class AspectDemo2 {@Before("com.example.springaop.aspect.AspectDemo1.pt()")public void beforeTest() {log.info("AspectDemo2 before 开始执行...");}
其中@before注解中的切点编写就是,提取方法的全限定路径+类名+方法名;
3.4@order切面优先级
假如定义了多个切⾯类时, 并且这些切⾯类的多个切⼊点都匹配到了同⼀个⽬标⽅法.情况如下所示

首先定义三个切面类,里面的通知方法大致如下:
public class AspectDemo3 {@Before("com.example.springaop.aspect.AspectDemo1.pt()")public void doBefore(){log.info("AspectDemo3 do before...");}@After("com.example.springaop.aspect.AspectDemo1.pt()")public void doAfter(){log.info("AspectDemo3 do after...");}}
此时进行路由访问后,打印的日志如下所示:

解释:
存在多个切⾯类时, 默认按照切⾯类的类名字⺟排序
• @Before 通知:字⺟排名靠前的先执⾏
• @After 通知:字⺟排名靠前的后执⾏
那么此时我们可以通过@order注解实现顺序的逆转,代码如下所示:
@Component
@Aspect
@Order(3)
public class AspectDemo3 {
}
解释:
我们设置 AspectDemo3order为3,AspectDemo4的order为2,AspectDemo5的order为1,输出的结果如下所示:

通过上述程序的运⾏结果, 得出结论:
@Order 注解标识的切⾯类, 执⾏顺序如下:
• @Before 通知:数字越⼩先执⾏
• @After 通知:数字越⼤先执⾏
@Order 控制切⾯的优先级, 先执⾏优先级较⾼的切⾯, 再执⾏优先级较低的切⾯, 最终执⾏⽬标⽅法
📚️4.总结
本期主要讲解了关于Spring AOP入门概念,以及快速入门,以及Spring AOP的代码的详细介绍:切点,连接点,通知,以及切面的概念,还有通知类型等其他注解的介绍~~~
🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!

💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。
😊😊 期待你的关注~~~
相关文章:
【Spring Boot】Spring AOP 快速上手指南:开启面向切面编程新旅程
前言 🌟🌟本期讲解关于spring aop的入门介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废话不…...
HTML基础入门——简单网页页面
目录 一,网上转账电子账单 编辑 1,所利用到的标签 2,代码编写 3,运行结果 二,李白诗词 1,所用到的标签 2,照片的编辑 3,代码编写 4,运行结果 一,网…...
INT301 Bio Computation 题型整理
perceptron 设计和计算 1. XOR: 当两个输入值中只有一个为真时,输出为真 2. 3. 5. 6. 7. 2^3 2^n 9. a) 直接test b) 把v≥2 改成 v≥1 10. no, because it cant be separate through only one decision boundary,its not linearlly separable. Backpropagatio…...
机器学习免费使用的数据集及网站链接
机器学习领域存在许多可以免费使用的数据集,这些数据集来自于学习、研究、比赛等目的。 一、综合性数据集平台 1.Kaggle 网址:Kaggle 数据集https://www.kaggle.com/datasets Kaggle是一个数据科学竞赛和社区平台,提供了大量的数据集供用…...
低空经济——飞行汽车运营建模求解问题思路
1. 掌握问题背景和领域知识 目标: 理解飞行汽车及其运营问题的核心要素和应用背景。学习内容: 飞行汽车基础: 了解飞行汽车的技术特点(垂直起降、电动推进等)。阅读行业报告,如 Uber Elevate 白皮书。共享…...
英伟达Project Digits赋能医疗大模型:创新应用与未来展望
英伟达Project Digits赋能医疗大模型:创新应用与未来展望 一、引言 1.1 研究背景与意义 在当今数字化时代,医疗行业作为关乎国计民生的关键领域,正面临着前所未有的挑战与机遇。一方面,传统医疗模式在应对海量医疗数据的处理、复…...
【Python3】异步操作 redis
aioredis 在高版本已经不支持了, 不要用 代码示例 redis 连接池异步操作redis以及接口 import asyncio from sanic import Sanic from sanic.response import json import redis.asyncio as redis from redis.asyncio import ConnectionPool# 创建 Sanic 应用 app…...
【W800】UART 的使用与问题
1.开发环境 OS: Windows 11开发板:海凌科 HLK-W800-KIT-PROSDK: W80X_SDK_v1.00.10IDE: CSKY Development Kit 2.UART 使用 在 SDK 中创建文件 uart_test.h 和 uart_test.c,然后在 CDK 项目中添加这两个文件,CDK 会自动 include 头文件。 …...
UART串口数据分析
串口基础知识详细介绍: 该链接详细介绍了串并行、单双工、同异步、连接方式 https://blog.csdn.net/weixin_43386810/article/details/127156063 该文章将介绍串口数据的电平变化、波特率计算、脉宽计算以及数据传输量的计算。 捕获工具:逻辑分析仪&…...
NFS 组件容器化部署实战指南
文章目录 前言部署NFS服务器K8S部署NFS问题记录 前言 使用nfs-client-provisioner这个应用,利用nfs server给kubernets提供作为持久化后端,并且动态提供pv。所有节点需要安装nfs-utils组件,并且nfs服务器与kubernets worker节点都能网络连通…...
嵌入式软件C语言面试常见问题及答案解析(三)
嵌入式软件C语言面试常见问题及答案解析(三) 上一篇已经足够长了,再长也就有点不礼貌了,所以在这儿继续来总结分享那个面试中遇到的题目,文中的问题和提供的答案或者代码均代表个人的理解,如有不合理或者错误的地方,欢迎大家批评指正。 本文中题目列表 1. 编码实现子串定…...
nvm安装教程
Node Version Manager (NVM) 是一个用来管理多个 Node.js 版本的命令行工具。使用 NVM,你可以在同一台机器上轻松安装和切换不同的 Node.js 版本。以下是针对 Unix 类系统(如 Linux 和 macOS)的 NVM 安装教程: 安装 NVM 更新系统…...
单片机-定时器中断
1、相关知识 振荡周期1/12us; //振荡周期又称 S周期或时钟周期(晶振周期或外加振荡周期)。 状态周期1/6us; 机器周期1us; 指令周期1~4us; ①51单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器…...
Hadoop 实战笔记(一) -- Windows 安装 Hadoop 3.x
环境准备 安装 JAVA 1.8 Java环境搭建之JDK下载及安装下载 Hadoop 3.3.5 安装包 Hadoop 下载:https://archive.apache.org/dist/hadoop/common/ 一、JAVA JDK 环境检查 二、Hadoop(HDFS)环境搭建 1. 解压安装文件 hadoop-3.3.5.tar 2. 配置环境变量 HADOOP_HO…...
AI中的神经元与权重矩阵之间的关系;神经元连接角度看行和列的意义
AI中的神经元与权重矩阵之间的关系 目录 AI中的神经元与权重矩阵之间的关系神经元连接角度看行和列的意义AI中的神经元概念 在人工智能领域,特别是神经网络中,神经元是基本的计算单元,它是对生物神经元的一种抽象模拟。就像生物神经元接收来自其他神经元的电信号,经过处理后…...
mysql、postgresql、druid链接池踩坑记录
The last packet successfully received from the server wIs 10,010 milliseconds ago. The last packet sent successfully to the server was 10,010 milliseconds ago.### The error may exist in URL mysql 链接字符串没有 &connectTimeout600000&socketTimeout6…...
NRF24L01模块STM32通信-通信初始化
目录 前言 一、IO口初始化 二、模拟SPI的基础代码 1.一些代码的宏定义 2.起始信号 3.CS,SCK,MOSI操作 4.MISO,IRQ操作 三.中间层代码 1.字节的输入和读取 2.写操作 3.读操作 四.应用层代码 1.24L01的检测 2.在main函数进行简单验证 3.24L01宏定义的代码 总结 前…...
高比例压缩:Linux 中的压缩命令与技巧
文章目录 高比例压缩:Linux 中的压缩命令与技巧1. 压缩格式的选择2. gzip 命令示例:压缩文件示例:解压文件 3. bzip2 命令示例:压缩文件示例:解压文件 4. xz 命令示例:压缩文件示例:解压文件 5.…...
LabVIEW软件Bug的定义与修改
在LabVIEW软件开发过程中,bug(程序错误或缺陷)指的是程序中导致不符合预期行为的任何问题。Bug可能是由于编码错误、逻辑漏洞、硬件兼容性问题、系统资源限制等因素引起的。它可能会导致程序崩溃、功能无法正常执行或输出结果不符合预期。理解…...
基于Springboot + vue实现的办公用品管理系统
🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
