Spring Boot使用AOP
一、为什么需要面向切面编程?
面向对象编程(OOP)的好处是显而易见的,缺点也同样明显。当需要为多个不具有继承关系的对象添加一个公共的方法的时候,例如日志记录、性能监控等,如果采用面向对象编程的方法,需要在每个对象里面都添加相同的方法,这样就产生了较大的重复工作量和大量的重复代码,不利于维护。面向切面编程(AOP)是面向对象编程的补充,简单来说就是统一处理某一“切面”的问题的编程思想。如果使用AOP的方式进行日志的记录和处理,所有的日志代码都集中于一处,不需要再每个方法里面都去添加,极大减少了重复代码。
二、Spring AOP术语

通知(Advice)包含了需要用于多个应用对象的横切行为,就是定义了“什么时候”和“做什么”。
连接点(Join Point)是程序执行过程中能够应用通知的所有点。
切点(Poincut)是定义了在“什么地方”进行切入,哪些连接点会得到通知。显然,切点一定是连接点。
切面(Aspect)是通知和切点的结合。通知和切点共同定义了切面的全部内容——是什么,何时,何地完成功能。
引入(Introduction)允许我们向现有的类中添加新方法或者属性。
织入(Weaving)是把切面应用到目标对象并创建新的代理对象的过程,分为编译期织入、类加载期织入和运行期织入。
三、Spring Boot AOP实战
1、引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.7.2</version>
</dependency>
不需要再添加aspectjweaver的依赖了,因为spring-boot-starter-aop包含了aspectjweaver
2、 编写用于拦截的bean
直接定义一个controller
@RestController
public class AopController {@GetMapping("/hello")public ResultMap sayHello(){ResultMap resultMap = new ResultMap();resultMap.setCode(1);resultMap.setMessage("响应成功");resultMap.setData("Hello World!");return resultMap;}
}
3、 定义切面
Spring采用@Aspect注解对POJO进行标注,该注解表明该类不仅仅是一个POJO,还是一个切面。切面是切点和通知的结合,那么定义一个切面就需要编写切点和通知。在代码中,只需要添加@Aspect注解即可。
(1)定义切点
切点是通过@Pointcut注解和切点表达式定义的。由于Spring切面粒度最小是达到方法级别,而execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且实际中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的。如图是execution表达式的语法:

execution表示在方法执行的时候触发。以“*”开头,表明方法返回值类型为任意类型。然后是全限定的类名和方法名,“*”可以表示任意类和任意方法。对于方法参数列表,可以使用“..”表示参数为任意类型。如果需要多个表达式,可以使用“&&”、“||”和“!”完成与、或、非的操作。
(2)定义通知
通知有五种类型,分别是:
前置通知(@Before):在目标方法调用之前调用通知
后置通知(@After):在目标方法完成之后调用通知
环绕通知(@Around):在被通知的方法调用之前和调用之后执行自定义的方法
返回通知(@AfterReturning):在目标方法成功执行之后调用通知
异常通知(@AfterThrowing):在目标方法抛出异常之后调用通知
@Aspect
@Component
public class AopAdvice {@Pointcut("execution(* com.mq.rabbit.controller.*.*(..))")public void pointCut(){}@Before("pointCut()")public void beforeAdvice(){System.out.println("\t------前置通知------");}@After("pointCut()")public void afterAdvice(){System.out.println("\t------后置通知------");}@Around("pointCut()")public Object aroundAdvice(ProceedingJoinPoint joinPoint) {System.out.println("------环绕通知开始------");Object result = null;try {result = joinPoint.proceed(); //接收Controller的返回值}catch (Throwable t){t.printStackTrace();}System.out.println("------环绕通知结束------");return result; //将Controller方法的返回值返回}
}
4、启动测试
运行项目,在浏览器访问http://localhost:端口号/项目名/hello,控制台输出如图所示:

相关文章:
Spring Boot使用AOP
一、为什么需要面向切面编程? 面向对象编程(OOP)的好处是显而易见的,缺点也同样明显。当需要为多个不具有继承关系的对象添加一个公共的方法的时候,例如日志记录、性能监控等,如果采用面向对象编程的方法&…...
C语言通过IXMLHttpRequest以get或post方式发送http请求获取服务器文本或xml数据
做过网页设计的人应该都知道ajax。 Ajax即Asynchronous Javascript And XML(异步的JavaScript和XML)。使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发…...
QtRVSim(二)一个 RISC-V 程序的解码流程
继上一篇文章简单代码分析后,本文主要调研如何实现对指令的解析运行。 调试配置 使用 gdb 工具跟踪调试运行。 c_cpp_properties.json 项目配置: {"name": "QtRvSim","includePath": ["${workspaceFolder}/**&quo…...
x-cmd pkg | httpx - 为 Python 设计的下一代 HTTP 客户端库
目录 简介首次用户功能特点进一步探索 简介 HTTPX 是一个为 Python 设计的下一代 HTTP 客户端库,由 Tom Christie 创建。它提供了同步和异步的 API,并支持 HTTP/1.1 和 HTTP/2 协议。与 Requests 库类似,但增加了对异步请求的支持和 HTTP/2 …...
代码随想录算法训练营第四十二天(动态规划篇)|62. 不同路径
62. 不同路径 题目链接:62. 不同路径 - 力扣(LeetCode) 思路 dp[i][j]: 从0到位置[i, j]共有dp[i][j]条路径。 dp[i][j] dp[i-1][j] dp[i][j-1] 到位置[i,j],可以从它的上面或者左边来,所以路径和为这两个方向的路…...
YOLO 全面回顾:从最初的YOLOv1到最新的YOLOv8、YOLO-NAS,以及整合了 Transformers 的 YOLO
YOLO 全面回顾 综述评估指标YOLO v1YOLO v2YOLO v3YOLO v4YOLOv5 与 Scaled-YOLOv4 YOLORYOLOXYOLOv6YOLOv7DAMO-YOLOYOLOv8PP-YOLO, PP-YOLOv2, and PP-YOLOEYOLO-NASYOLO with Transformers 综述 论文:https://arxiv.org/pdf/2304.00501.pdf 代码:gi…...
Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)
Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2) 在 Android ScaleGestureDetector检测双指缩放Bitmap基于Matrix动画移动到双指捏合中心点ImageView区域中心,Kotlin-CSDN博客 …...
同为科技(TOWE)自动控制循环定时插座
随着科技的发展,智能化家居已成为我们生活的重要组成部分。作为国内领先的智能家居品牌,同为科技(TOWE)推出的自动控制循环定时插座,无疑将科技与生活完美地结合在一起。 1.外观设计 同为科技(TOWE&#x…...
游戏设计模式
单列模式 概念 单例模式是一种创建型设计模式,可以保证一个类只有一个实例,并提供一个访问该实例的全局节点。 优点 可以派生:在单例类的实例构造函数中可以设置以允许子类派生。受控访问:因为单例类封装他的唯一实例…...
CUBEMX与FreeRTOS在Arm Compiler 6下的配置方法
在嵌入式开发中,STM32是一种广泛使用的微控制器。为了提高开发效率,我们通常会利用ST公司提供的STM32CubeMX工具来配置硬件,并结合FreeRTOS这一实时操作系统来进行多任务处理。本文将深入探讨如何在这一框架下,使用Arm Compiler 6…...
Android Studio 提示Use app:drawableStartCompat instead of android:drawableStart
每次提交代码时,AS这个老妈子总爱唠叨一堆warning,这些Warning都在讲什么? 1.Use app:drawableStartCompat instead of android:drawableStart 在Android开发中,android:drawableStart和app:drawableStartCompat是两个用于设置…...
C# wpf 实现任意控件(包括窗口)更多调整大小功能
WPF拖动改变大小系列 第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小 第五章 拓展更多调整大小功能(本章) 文章目录 WPF拖动改变大小系列前言一、添加的功能1、任意控件Drag…...
Vue+OpenLayers7入门到实战:快速搭建Vue+OpenLayers7地图脚手架项目。从零开始构建Vue项目并整合OpenLayers7.5.2
返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7 前言 本章针对Vue初学者,对Vue不熟悉,甚至还不会Vue的入门学生读者。 本章会详细讲解从NodeJS环境到npm环境的各个步骤,再到使用vue-cli脚手架快速生成项目,以及添加OpenLayers7地图库依赖,编写简单的xyz高德地图显示…...
mysql-线上常用运维sql
1.表备份 INSERT INTO table1 SELECT * FROM table2; 2.用一个表中的字段更新另一张表中的字段 UPDATE table2 JOIN table1 ON table2.id table1.id SET table2.column2 table1.column1; 3.在MySQL中,查询一个表的列字段值是否包含另一个表的字段,…...
Linux之进程间通信(system V 共享内存)
目录 一、共享内存 1、基本原理 2、共享内存的创建 3、共享内存的释放 4、共享内存的关联 5、共享内存的去关联 6、查看IPC资源 二、完整通信代码 三、共享内存的特点 四、信号量 1、相关概念 2、信号量概念 进程间通信的本质就是让不同的进程看到同一个资源。而前…...
数据库 sql select *from account where name=‘张三‘ 执行过程
select *from account where name张三分析上面语句的执行过程 用到了索引 由于是根据 1.name字段进行查询,所以先根据name张三’到name字段的二级索引中进行匹配查 找。但是在二级索引中只能查找到 Arm 对应的主键值 10。 2.由于查询返回的数据是*,…...
力扣日记1.27-【回溯算法篇】131. 分割回文串
力扣日记:【回溯算法篇】131. 分割回文串 日期:2023.1.27 参考:代码随想录、力扣 131. 分割回文串 题目描述 难度:中等 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可…...
如何用web界面打开华为防火墙
目录 1.创建一个虚拟网卡 2.cloud操作 3.防火墙上操作 4. 登录 1.创建一个虚拟网卡 2.cloud操作 3.防火墙上操作 4. 登录...
力扣20、有效的括号(简单)
1 题目描述 图1 题目描述 2 题目解读 给定的字符串只包含括号,判断这个字符串中的括号是否按照正确顺序出现,即这个字符串是否有效。 3 解法一:栈 C的STL中的stack,在解题时非常好用。 3.1 解题思路 使用栈stk,并枚举…...
Android 系统启动过程
当按下电源时,引导芯片代码会从预定义的地方(固化在ROM) 开始执行,加载引导程序BootLoader到RAM,然后执行。 启动内核的第一个进程idle(pid0),idle进程是Linux系统第一个进程,是init进程和kthreadd进程的父进程。 idle的主要作用 初始化进程以及内存管…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
