Spring AOP详解
Spring AOP是Spring框架中的一个模块,它允许开发人员使用面向切面编程(AOP)的思想来解耦系统的不同层次。
Spring AOP的核心概念是切面(aspect)、连接点(join point)、通知(advice)、切点(pointcut)和引入(introduction)。
- 切面(aspect):切面是一个类, 它包含了通知(advice)和切点(pointcut)。
- 连接点(join point):在AOP中,连接点是程序执行的某个时间点,例如方法调用、异常抛出、对象实例化等。
- 通知(advice):在连接点上执行的代码片段,它们包括before、after、afterReturning、afterThrowing和around五种类型。
- 切点(pointcut):在程序执行时选择哪些连接点执行通知的表达式,例如execution(* com.example.demo.*(..))表示匹配com.example.demo包下的任意方法。
- 引入(introduction):在不修改现有类代码的情况下,向现有类添加新方法或属性。
Spring AOP底层使用动态代理和字节码生成来实现。切面由通知和切点组成,连接点是程序执行的某个时间点,切点根据表达式匹配连接点,通知是在连接点上执行的代码片段,在方法调用前或调用后执行某些操作。
Spring AOP的优点是可以通过配置实现解耦,不用修改经常变动的业务逻辑代码,而且可以重用通知,降低代码冗余程度。
以下是一个使用Spring Boot AOP实现日志记录的例子:
1.创建一个Spring Boot项目并添加如下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.定义一个"UserService"接口和一个实现类"UserServiceImpl",实现类中包含一个方法"getUserById":
public interface UserService {User getUserById(long id);
}@Service
public class UserServiceImpl implements UserService {@Overridepublic User getUserById(long id) {System.out.println("调用getUserById方法,id=" + id);return new User(id, "张三");}
}
3.定义一个切面"LogAspect",
使用注解@Aspect标识切面,
使用@Pointcut定义切点,
使用
@Before、
@After、
@AfterReturning、
@AfterThrowing、
@Around注解定义通知:
@Aspect
@Component
public class LogAspect {@Pointcut("execution(* com.example.demo.service.UserService.*(..))")public void userServicePointcut() {}@Before("userServicePointcut()")public void before(JoinPoint joinPoint) {System.out.println("调用" + joinPoint.getSignature().getName() + "方法");}@AfterReturning(pointcut = "userServicePointcut()", returning = "result")public void afterReturning(JoinPoint joinPoint, Object result) {System.out.println("调用" + joinPoint.getSignature().getName() + "方法完成,返回值=" + result);}@AfterThrowing(pointcut = "userServicePointcut()", throwing = "exception")public void afterThrowing(JoinPoint joinPoint, Exception exception) {System.out.println("调用" + joinPoint.getSignature().getName() + "方法出现异常,异常信息=" + exception.getMessage());}
}
在上面的切面中,我们使用@Pointcut注解定义切点,使用@Before、@AfterReturning、@AfterThrowing等注解定义通知,在通知中使用JoinPoint获取方法签名、参数等信息,输出日志。
4.运行应用程序并测试:
@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/user/{id}")public User getUser(@PathVariable long id) {return userService.getUserById(id);}
}
在控制台中可以看到如下输出:
调用getUserById方法,id=1
调用getUserById方法完成,返回值=User [id=1, name=张三]
匹配方法
Pointcut是基于表达式的描述符,用于指定应该在哪些方法上执行通知。Pointcut表达式可以使用AspectJ的语法,也可以使用Spring AOP的语法。
以下是常用的Pointcut表达式:
- execution:使用该表达式匹配方法执行的切点。
-
execution(public * com.example.demo.service.UserService.*(..)):匹配com.example.demo.service.UserService类中所有public修饰符的方法。
-
execution(* com.example.demo.service..(..)):匹配com.example.demo.service包下所有类的任意方法。
-
execution(* com.example.demo.service...(..)):匹配com.example.demo.service包以及其子包下所有类的任意方法。
- within:使用该表达式匹配指定类型的切点,包括该类型的子类型。
-
within(com.example.demo.service.*):匹配所有com.example.demo.service包中的类型。
-
within(com.example.demo.service..*):匹配com.example.demo.service包以及其子包中的所有类型。
- annotation:使用该表达式匹配带有指定注解的切点。
-
@annotation(org.springframework.web.bind.annotation.RequestMapping):匹配带有@RequestMapping注解的方法。
-
@within(org.springframework.stereotype.Service):匹配带有@Service注解的类中的所有方法。
- args:使用该表达式匹配带有指定参数类型的切点。
-
args(java.lang.String):匹配一个参数类型为String的方法。
-
args(java.lang.String, ...):匹配至少一个参数类型为String的方法。
- bean:使用该表达式匹配指定名称或类型的bean的切点。
-
bean(userService):匹配名称为userService的bean。
-
bean(userService*):匹配名称以userService开头的bean。
除了以上的表达式外,还有很多其他的表达式,可以根据具体的需求选择使用。需要注意的是,在使用Pointcut表达式时,需要注意匹配的粒度,匹配过于精确会导致无法匹配到需要的切点,匹配过于宽泛则会匹配到不需要的切点。
相关文章:
Spring AOP详解
Spring AOP是Spring框架中的一个模块,它允许开发人员使用面向切面编程(AOP)的思想来解耦系统的不同层次。 Spring AOP的核心概念是切面(aspect)、连接点(join point)、通知(advice)、切点(pointcut)和引入(introduction)。 切面(aspect):切面是一个类, 它…...
linux iptables安全技术与防火墙
linux iptables安全技术与防火墙 1、iptables防火墙基本介绍1.1netfilter/iptables关系1.2iptables防火墙默认规则表、链结构 2、iptables的四表五链2.1四表2.2五链2.3四表五链总结2.3.1 规则链之间的匹配顺序2.3.2 规则链内的匹配顺序 3、iptables的配置3.1iptables的安装3.2i…...
TCP性能机制
延迟应答 为什么有延迟应答 发送方如果长时间没有收到ACK应答,则会触发超时重传机制,重新发送数据包。但如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小,发送方一次只能发少量数据,效率较低。 举个例子理解一…...
qt信号槽同步问题
目录 信号槽: 注意事项: 具体例子: 线程安全问题的例子: 信号槽: 在Qt编程中,信号(Signal)和槽(Slot)是一种用于在对象之间进行通信的机制。信号用于发出…...
七夕特惠-8折抢购,从速
在七夕这个特殊的日子,我们推出了8折优惠活动,具体如下: 不管是充值会员,还是购买套路文章,一律享受8折优惠,活动截止时间为2023年8月24日12时。 甚至还有免费抽奖活动 兑奖方式,复制兑奖码…...
[NLP]LLM--transformer模型的参数量
1. 前言 最近,OpenAI推出的ChatGPT展现出了卓越的性能,引发了大规模语言模型(Large Language Model, LLM)的研究热潮。大规模语言模型的“大”体现在两个方面:模型参数规模大,训练数据规模大。以GPT3为例,GPT3的参数量…...
5 Python的面向对象编程
概述 在上一节,我们介绍了Python的函数,包括:函数的定义、函数的调用、参数的传递、lambda函数等内容。在本节中,我们将介绍Python的面向对象编程。面向对象编程(Object-Oriented Programming, 即OOP)是一种…...
卷积神经网络——上篇【深度学习】【PyTorch】【d2l】
文章目录 5、卷积神经网络5.1、卷积5.1.1、理论部分5.1.2、代码实现5.1.3、边缘检测 5.2、填充和步幅5.2.1、理论部分5.2.2、代码实现 5.3、多输入多输出通道5.3.1、理论部分5.3.2、代码实现 5.4、池化层 | 汇聚层5.4.1、理论部分5.4.2、代码实现 5、卷积神经网络 5.1、卷积 …...
【从零学习python 】54. 内存中写入数据
文章目录 内存中写入数据StringIOBytesIO进阶案例 内存中写入数据 除了将数据写入到一个文件以外,我们还可以使用代码,将数据暂时写入到内存里,可以理解为数据缓冲区。Python中提供了StringIO和BytesIO这两个类将字符串数据和二进制数据写入…...
速通蓝桥杯嵌入式省一教程:(九)AT24C02芯片(E2PROM存储器)读写操作与I2C协议
AT24C02芯片(又叫E2PROM存储器、EEPROM存储器),是一种通过I2C(IIC)协议通信的掉电保存存储器芯片,其内部含有256个8位字节。在介绍这款芯片之前,我们先来粗略了解一下I2C协议。 I2C总线是一种双向二线制的同步串行总线…...
负载均衡:优化性能与可靠性的关键
在现代互联网时代,数以万计的用户访问着各种在线服务,从即时通讯、社交媒体到电子商务和媒体流媒体,无不需要应对海量的请求和数据传输。在这个高并发的环境下,负载均衡成为了关键的技术,它旨在分散工作负载࿰…...
T113-S3-TCA6424-gpio扩展芯片调试
目录 前言 一、TCA6424介绍 二、原理图连接 三、设备树配置 四、内核配置 五、gpio操作 总结 前言 TCA6424是一款常用的GPIO(通用输入输出)扩展芯片,可以扩展微控制器的IO口数量。在T113-S3平台上,使用TCA6424作为GPIO扩展芯…...
奥威BI数据可视化工具:个性化定制,打造独特大屏
每个人都有自己独特的审美,因此即使是做可视化大屏,也有很多人希望做出不一样的报表,用以缓解审美疲劳的同时提高报表浏览效率。因此这也催生出了数据可视化工具的个性化可视化大屏制作需求。 奥威BI数据可视化工具:个性化定制&a…...
13 秒插入 30 万条数据,批量插入!
数据库表 CREATE TABLE t_user (id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户id,username varchar(64) DEFAULT NULL COMMENT 用户名称,age int(4) DEFAULT NULL COMMENT 年龄,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8 COMMENT用户信息表; User实体 /*** …...
Nginx代理转发地址不正确问题
使用ngix前缀去代理转发一个地址,貌似成功了,但是进不到正确的页面,能够访问,但是一直404远处出来nginx会自动拼接地址在后面 后面才知道要将这段代码加上去,去除前缀转发...
HyperMotion高度自动化云迁移至华为HCS8.1解决方案
项目背景 2020 年以来,金融证券已经成为信创落地最快的领域。2021 年证监会发布的《证券期货业科技发展十四五规划》中,将“加强信创规划与实施”作为证券行业重点建设任务之一。为了符合国家信创标准,某证券企业计划将网管系统、呼叫中心管…...
pbootcms系统安全防护设置大全
PbootCMS系统简介 PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统,是一套高效、简洁、 强悍的可免费商用的PHP CMS源码,能够满足各类企业网站开发建设的需要。系统采用简单到想哭的模板标签,只要懂HTML就可快速开发企业网站…...
【环境】docker时间与宿主同步
1.容器创建后 docker cp /etc/localtime 容器名:/etc/2.容器创建时 加入 -v /ect/localtime/:/etc/localtime:ro参考链接...
亮点!视频云存储/安防监控视频智能分析平台睡岗离岗检测
在生产过程中,未经领导允许的擅自离岗、睡岗会带来很多的潜在危害。TSINGSEE青犀推出的视频云存储/安防监控视频智能分析平台得睡岗离岗检测根据AI视频分析技术建立人工智能算法,对视频画面展开分析与识别。自动识别出人员睡岗、离岗、玩手机与抽烟等动作…...
编程锦囊妙计——快速创建本地Mock服务
点击上方👆蓝色“Agilean”,发现更多精彩。 前情提要 在本系列上一篇文章《全文干货:打破前后端数据传递鸿沟,高效联调秘笈》中我们分享了使用Zod这一运行时类型校验库来对后端服务响应结果进行验证达到增加项目质量的方式。 这次…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
