Spring Boot Aop初接触
AOP(面向切面编程),或多或少都听过一点。名字比较怪,切面,不容易理解,但其中真正含义,无非就是旁路控制,非侵入式编码之类。比如我想加个操作日志功能,利用AOP,无须每个操作都加一个记录功能,只需写一个,就惠泽全部。
这个是怎么做到的呢?也没有太玄妙的东西,原理类似于过滤器、拦截器,在底层和全局性的地方做了处理,各个业务功能都流经这些关卡。

一、过滤器、拦截器与AOP
据说,过滤器、拦截器、AOP三者功能类似,但各有优势,从过滤器 》拦截器 》切面,拦截规则越来越细致,执行顺序依次是过滤器、拦截器、切面。一般情况下数据被过滤的时机越早对服务的性能影响越小,因此我们在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是AOP。
AOP使用的主要是动态代理 , 过滤器使用的主要是函数回调;拦截器使用是反射机制 。一个请求过来,先进行过滤器处理,看程序是否受理该请求 。 过滤器放过后 , 程序中的拦截器进行处理 ,处理完后进入 被 AOP动态代理重新编译过的主要业务类进行处理 。
Filter:和框架无关,过滤器拦截的是URL,可以控制最初的http请求,但是更细一点的类和方法控制不了。
Interceptor:拦截器拦截的也是URL,拦截器有三个方法,相对于过滤器更加细致,有被拦截逻辑执行前、后等。
AOP:面向切面拦截的是类的元数据(包、类、方法名、参数等) 相对于拦截器更加细致,而且非常灵活,拦截器只能针对URL做拦截,而AOP针对具体的代码,能够实现更加复杂的业务逻辑。
二、Spring Boot中应用AOP
1、pom.xml
引入依赖包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、面向切面类
1)写一个方法用于测试
为方便测试,写一个控制器。再简单不过的控制器。
TestController.java
package com.chenqu.bullshit.modules.work.controller;@RestController
@RequestMapping("test1")
public class TestController {@ResponseBody@RequestMapping("/hello")public String sayHello(){System.out.println("hello");return "hello";}
}
2)面向切面的类
然后写一个面向切面的类。就像配置、过滤器、拦截器一样,写出来之后,系统(准确来说,应该是容器?)会自动解释它,于是面向切面开始生效。
TestAdvice.java
@Aspect
@Component
public class TestAdvice {//指示哪些方法将会受到影响。Pointcut,切入点@Pointcut("execution (* com.chenqu.bullshit.modules.work.controller.TestController.*(..))")public void test1() {}@Before("test1()")public void beforeAdvice() {System.out.println("beforeAdvice...");}@After("test1()")public void afterAdvice() {System.out.println("afterAdvice...");}@Around("test1()")public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {System.out.println("before");try {proceedingJoinPoint.proceed();} catch (Throwable t) {t.printStackTrace();}System.out.println("after");}
}
上述代码中,首先类使用了标注“@Aspect”,表明这是一个面向切面的类。
类中void test1()使用了标注“@Pointcut”。Pointcut者,切入点也。它里面的内容,指示了哪些方法将会受到影响。在这里,指向了我们用于测试的控制器。如果是想指向所有的控制器,可以这样写:
@Pointcut("execution (* com.chenqu.bullshit.modules.work.controller.*.*(..))")

至于其他的什么@Before、@After、@Arround,无非就是切入前执行、切入后执行、切入时执行,顾名思义。
运行代码,用浏览器访问
http://localhost:8090/test1/hello
控制台输出如下:

3、execution 与 annotation
execution与annotation都是Pointcut的2种常用执行方式,除此而外,还有什么within、this、target之类乱七八糟的,一大群,让人头大。常用的就是execution与annotation。execution如上例,就是指明会影响哪些方法;而annotation是注解的意思,指明会影响带哪些注解的方法,或者说,如果方法带上指定的注解,就会受到影响。
1)添加一个名为NeedTest的注解
NeedTest.java
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NeedTest {String value() default "";
}
2)然后将上面例子中TestAdvice.java,Pointcut的执行方式由execution 改为 annotation,其余保持不变。
@Aspect
@Component
public class TestAdvice {@Pointcut("@annotation(com.chenqu.bullshit.modules.annotation.NeedTest)")public void test1() {}@Before("test1()")public void beforeAdvice() {System.out.println("beforeAdvice...");}@After("test1()")public void afterAdvice() {System.out.println("afterAdvice...");}@Around("test1()")public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {System.out.println("before");try {proceedingJoinPoint.proceed();} catch (Throwable t) {t.printStackTrace();}System.out.println("after");}}
3)修改用于测试的控制器TestController.java,方法带上@NeedTest注解
package com.chenqu.bullshit.modules.work.controller;@RestController
@RequestMapping("test1")
public class TestController {@NeedTest@ResponseBody@RequestMapping("/hello")public String sayHello(){System.out.println("hello");return "hello";}
}
运行结果跟上面一样,效果一致。
三、小结
从网上搜索出来的,有关spring boot aop的使用资料,绝大部分都很难懂。说了一大堆,根本不知道在说什么,也许作为手册供查阅是极好的。本文从我个人学习的角度出发,记录一下心得。
参考文章:
Spring Boot使用AOP的正确姿势
相关文章:
Spring Boot Aop初接触
AOP(面向切面编程),或多或少都听过一点。名字比较怪,切面,不容易理解,但其中真正含义,无非就是旁路控制,非侵入式编码之类。比如我想加个操作日志功能,利用AOP࿰…...
【创作赢红包】LeetCode:232. 用栈实现队列
🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱232. 用栈实现队列 题目描述:请你仅使用两个栈实现先入先出队…...
Mybatis+Mysql 实现向下递归查询
介绍 说到递归查询,大家可以想到的技术实现方式主要如下几种: 1、各种主流应用开发语言本身通过算法实现 2、各种数据库引擎自身提供的算法实现 本文提到主要是针对第二种和第一种的结合 主要技术栈 1、ORM:Mybatis 2、DB:MyS…...
python@调用系统命令行@os.system@subprocess@标准输入输出@sys.stdin@sys.stdout@input@print
文章目录python调用系统命令行os.system标准输入输出sys.stdinsys.stdoutinputprint概要os.systemdemoswindows命令解释器ComSpecsubprocessrecommended🎈基本用法demos标准输入输出sys.stdininput()sys.stdin.inputinput()交互模式小结sys.stdoutsys.stdout.wirte(…...
手握数据智能密钥,诸葛智能打开数字化经营“三重门”
科技云报道原创。 如果说上世纪传统麦迪逊大街上的“广告狂人”吸金立足之本,还主要是基于“Big Idea”的话,那么在当下,数据正在成为企业营销和运营的金矿。 这是一个“人与机器共同进化”的时代,技术作为延伸人类感觉的媒介之…...
C语言可以实现各种滤波算法
C语言可以实现各种滤波算法,以下是一些常见的滤波算法: 均值滤波(Mean Filter):将图像中每一个像素周围一定区域内的灰度值取平均值作为该像素的新灰度值,用于去除高斯噪声等随机噪声。 下面是一个简单的 C…...
使用Netty,当然也要了解它的连接闲置处理
连接闲置网络连接的闲置指的是当前网络连接处于空闲状态,即没有正在进行的数据传输或通信活动。当我们的某个连接不再发送请求或者接收响应的时候,这个连接就开始处于闲置状态。网络连接的闲置时间越长,说明该连接越不活跃。此时,…...
2、K-Planes
运行配置 主页:https://sarafridov.github.io/K-Planes/ 代码:https://github.com/sarafridov/K-Planes 预训练权重:https://drive.google.com/drive/folders/1zs_folzaCdv88y065wc6365uSRfsqITH Neural_3D_Video_Dataset:htt…...
张文海教授课题组在国际高水平期刊《Cerebral Cortex》发表研究成果
调节悲伤情绪对于维持伴侣间的浪漫关系至关重要。人际情绪调节策略包括情感参与(AE)和认知参与(CE),这两种策略在浪漫关系中效用如何?它们是如何通过情感纽带调节伴侣情绪的?其背后的脑际神经互…...
ffmpeg4.1 源码学习之-转封装
前言 ffmpeg 的源码量非常的多,而且非常繁杂,非常多的函数,如果一个函数一个函数看的话要花费比较多的时间。所以本文通过跟踪ffmpeg转封装的过程来学习ffmpeg的源码具体转封装的命令:ffmpeg -i 1_cut.flv -c copy -f mp4 1.mp4在…...
ChatGPT写作文章-快速使用ChatGPT不用注册方式
如何更好地使用ChatGPT批量生成文章:详细教程 作为一款强大的文本生成器,ChatGPT可以帮助您快速、高效地批量生成文章。但如果您还不知道如何更好地使用ChatGPT,那么这篇详细的列表教程将会指导您如何使用它来生成高质量的文章,提…...
Nginx配置ip白名单(服务权限控制)
Nginx服务器权限控制:Nginx 是一款高性能的 HTTP 和反向代理服务器。它可以通过配置文件实现权限控制,从而限制或允许特定的 IP 地址、网络或用户访问指定的资源。这里是一些基本的 Nginx 权限控制方法: 1. 基于 IP 地址的访问控制 在 Ngin…...
Vue 核心(二)
文章目录Vue 核心(二)八、 绑定样式1、 class2、 style九、 条件渲染1、 渲染指令2、 使用示例十、 列表渲染1、 基本语法2、 key原理3、 列表过滤4、 列表排序5、 数组更新检测6、 大总结十一、 收集表单数据十二、 内置指令1、 v-text2、 v-html3、 v-…...
犯罪现场还原虚拟vr训练平台突破各种教学限制
在当今社会矛盾日益凸显、各式犯罪层出不穷的背景下,创新改革公安院校实战化教学方式,强化对基层公安队伍实战化应用型人才的供给能力具有重要性、紧迫性。 案件现场勘查是门技术活,如何让民警快速有效提升技能、服务实战? 常规刑侦专业现场…...
LeetCode 617. 合并二叉树 | C++语言版
LeetCode 617. 合并二叉树 | C语言版LeetCode 617. 合并二叉树题目描述解题思路思路一:使用递归代码实现运行结果参考文章:思路二:减少遍历节点数代码实现运行结果参考文章:LeetCode 617. 合并二叉树 题目描述 题目地址…...
Python量化交易08——利用Tushare获取日K数据
总有同学问我要数据...很多第三方接口都能直接获取数据的,本次介绍怎么用Tushare库获取A股日k线行情的数据。 Tushare有两个版本,老版现在快弃用了。 新版的官网链接在这:Tushare数据 需要注册一个账号,然后改一下资料࿰…...
30张精美可视化大屏,无需代码直接套用,解决你95%的大屏需求!
通常制作可视化大屏,一般有两种方式 代码开发:写代码调用数据和图表库,比如写JSEcharts ; 可视化工具:用现成的数据可视化工具 前者简单直接,直接写代码就完事。但对于大部分人来说门槛较高,维…...
TCP网络事件模型的封装1.0
TCP网络模型的封装 最近学习了TCP网络模型的封装,其中运用的封装技术个人感觉有点绕 在反复读代码、做思维导图下初步理解了这套封装模型,不禁感叹原来代码还能这样写?神奇! 为此将源码分享出来并将流程图画出,方便…...
NC271.二叉搜索树的后序遍历序列
文章目录一、题目描述二、示例三、主要思路一、题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。 提示: 1.二叉搜索树是指父亲节点大于左子树中…...
研究fastdds v2.8.0 1之 基础模块
阅读 dds 协议 1.4 版本 , 结合fastdds 2.8 的代码理解dds。 Entity 理解 DCPS基础设施模块由以下类组成: Entity DomainEntity QosPolicy Listener Status WaitSet Condition GuardCondition StatusCondition1、Entity 是所有DCPS 对象的基础类 virt…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
