【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实现的办公用品管理系统
🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...

五、jmeter脚本参数化
目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...