当前位置: 首页 > news >正文

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表达式:

  1. 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包以及其子包下所有类的任意方法。

  1. within:使用该表达式匹配指定类型的切点,包括该类型的子类型。
  • within(com.example.demo.service.*):匹配所有com.example.demo.service包中的类型。

  • within(com.example.demo.service..*):匹配com.example.demo.service包以及其子包中的所有类型。

  1. annotation:使用该表达式匹配带有指定注解的切点。
  • @annotation(org.springframework.web.bind.annotation.RequestMapping):匹配带有@RequestMapping注解的方法。

  • @within(org.springframework.stereotype.Service):匹配带有@Service注解的类中的所有方法。

  1. args:使用该表达式匹配带有指定参数类型的切点。
  • args(java.lang.String):匹配一个参数类型为String的方法。

  • args(java.lang.String, ...):匹配至少一个参数类型为String的方法。

  1. bean:使用该表达式匹配指定名称或类型的bean的切点。
  • bean(userService):匹配名称为userService的bean。

  • bean(userService*):匹配名称以userService开头的bean。

除了以上的表达式外,还有很多其他的表达式,可以根据具体的需求选择使用。需要注意的是,在使用Pointcut表达式时,需要注意匹配的粒度,匹配过于精确会导致无法匹配到需要的切点,匹配过于宽泛则会匹配到不需要的切点。

相关文章:

Spring AOP详解

Spring AOP是Spring框架中的一个模块&#xff0c;它允许开发人员使用面向切面编程(AOP)的思想来解耦系统的不同层次。 Spring AOP的核心概念是切面(aspect)、连接点(join point)、通知(advice)、切点(pointcut)和引入(introduction)。 切面(aspect)&#xff1a;切面是一个类, 它…...

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应答&#xff0c;则会触发超时重传机制&#xff0c;重新发送数据包。但如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小&#xff0c;发送方一次只能发少量数据&#xff0c;效率较低。 举个例子理解一…...

qt信号槽同步问题

目录 信号槽&#xff1a; 注意事项&#xff1a; 具体例子&#xff1a; 线程安全问题的例子&#xff1a; 信号槽&#xff1a; 在Qt编程中&#xff0c;信号&#xff08;Signal&#xff09;和槽&#xff08;Slot&#xff09;是一种用于在对象之间进行通信的机制。信号用于发出…...

七夕特惠-8折抢购,从速

在七夕这个特殊的日子&#xff0c;我们推出了8折优惠活动&#xff0c;具体如下&#xff1a; 不管是充值会员&#xff0c;还是购买套路文章&#xff0c;一律享受8折优惠&#xff0c;活动截止时间为2023年8月24日12时。 甚至还有免费抽奖活动 兑奖方式&#xff0c;复制兑奖码…...

[NLP]LLM--transformer模型的参数量

1. 前言 最近&#xff0c;OpenAI推出的ChatGPT展现出了卓越的性能&#xff0c;引发了大规模语言模型(Large Language Model, LLM)的研究热潮。大规模语言模型的“大”体现在两个方面&#xff1a;模型参数规模大&#xff0c;训练数据规模大。以GPT3为例&#xff0c;GPT3的参数量…...

5 Python的面向对象编程

概述 在上一节&#xff0c;我们介绍了Python的函数&#xff0c;包括&#xff1a;函数的定义、函数的调用、参数的传递、lambda函数等内容。在本节中&#xff0c;我们将介绍Python的面向对象编程。面向对象编程&#xff08;Object-Oriented Programming, 即OOP&#xff09;是一种…...

卷积神经网络——上篇【深度学习】【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进阶案例 内存中写入数据 除了将数据写入到一个文件以外&#xff0c;我们还可以使用代码&#xff0c;将数据暂时写入到内存里&#xff0c;可以理解为数据缓冲区。Python中提供了StringIO和BytesIO这两个类将字符串数据和二进制数据写入…...

速通蓝桥杯嵌入式省一教程:(九)AT24C02芯片(E2PROM存储器)读写操作与I2C协议

AT24C02芯片&#xff08;又叫E2PROM存储器、EEPROM存储器&#xff09;&#xff0c;是一种通过I2C(IIC)协议通信的掉电保存存储器芯片&#xff0c;其内部含有256个8位字节。在介绍这款芯片之前&#xff0c;我们先来粗略了解一下I2C协议。 I2C总线是一种双向二线制的同步串行总线…...

负载均衡:优化性能与可靠性的关键

在现代互联网时代&#xff0c;数以万计的用户访问着各种在线服务&#xff0c;从即时通讯、社交媒体到电子商务和媒体流媒体&#xff0c;无不需要应对海量的请求和数据传输。在这个高并发的环境下&#xff0c;负载均衡成为了关键的技术&#xff0c;它旨在分散工作负载&#xff0…...

T113-S3-TCA6424-gpio扩展芯片调试

目录 前言 一、TCA6424介绍 二、原理图连接 三、设备树配置 四、内核配置 五、gpio操作 总结 前言 TCA6424是一款常用的GPIO&#xff08;通用输入输出&#xff09;扩展芯片&#xff0c;可以扩展微控制器的IO口数量。在T113-S3平台上&#xff0c;使用TCA6424作为GPIO扩展芯…...

奥威BI数据可视化工具:个性化定制,打造独特大屏

每个人都有自己独特的审美&#xff0c;因此即使是做可视化大屏&#xff0c;也有很多人希望做出不一样的报表&#xff0c;用以缓解审美疲劳的同时提高报表浏览效率。因此这也催生出了数据可视化工具的个性化可视化大屏制作需求。 奥威BI数据可视化工具&#xff1a;个性化定制&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前缀去代理转发一个地址&#xff0c;貌似成功了&#xff0c;但是进不到正确的页面&#xff0c;能够访问&#xff0c;但是一直404远处出来nginx会自动拼接地址在后面 后面才知道要将这段代码加上去&#xff0c;去除前缀转发...

HyperMotion高度自动化云迁移至华为HCS8.1解决方案

项目背景 2020 年以来&#xff0c;金融证券已经成为信创落地最快的领域。2021 年证监会发布的《证券期货业科技发展十四五规划》中&#xff0c;将“加强信创规划与实施”作为证券行业重点建设任务之一。为了符合国家信创标准&#xff0c;某证券企业计划将网管系统、呼叫中心管…...

pbootcms系统安全防护设置大全

PbootCMS系统简介 PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统&#xff0c;是一套高效、简洁、 强悍的可免费商用的PHP CMS源码&#xff0c;能够满足各类企业网站开发建设的需要。系统采用简单到想哭的模板标签&#xff0c;只要懂HTML就可快速开发企业网站…...

【环境】docker时间与宿主同步

1.容器创建后 docker cp /etc/localtime 容器名:/etc/2.容器创建时 加入 -v /ect/localtime/:/etc/localtime:ro参考链接...

亮点!视频云存储/安防监控视频智能分析平台睡岗离岗检测

在生产过程中&#xff0c;未经领导允许的擅自离岗、睡岗会带来很多的潜在危害。TSINGSEE青犀推出的视频云存储/安防监控视频智能分析平台得睡岗离岗检测根据AI视频分析技术建立人工智能算法&#xff0c;对视频画面展开分析与识别。自动识别出人员睡岗、离岗、玩手机与抽烟等动作…...

编程锦囊妙计——快速创建本地Mock服务

点击上方&#x1f446;蓝色“Agilean”&#xff0c;发现更多精彩。 前情提要 在本系列上一篇文章《全文干货&#xff1a;打破前后端数据传递鸿沟&#xff0c;高效联调秘笈》中我们分享了使用Zod这一运行时类型校验库来对后端服务响应结果进行验证达到增加项目质量的方式。 这次…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...