SpringBoot使用AOP详解
目录
- 1 AOP是什么
- 2 AOP概念
- 3 Springboot中使用AOP
- 4 AOP原理
- 5 应用场景
1 AOP是什么
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。
利用AOP可对业务逻辑进行增强,在不改变原有逻辑的基础上,在其前后进行处理。降低了耦合性,减少了大量冗余的操作。特别适合用于大量方法都需要进行相同处理的操作。
2 AOP概念
AOP是做了个切面,在不破坏原有方法的基础上,将切面切进去,在其前后进行处理,整体逻辑关系图如下:
- 切面(Aspect):一般是指被
@Aspect
修饰的类,代表着某一具体功能的AOP
逻辑。 - 切入点(Pointcut):选择对哪些方法进行增强。
- 通知(Advice):对目标方法的增强,有一下五种增强的类型。
- 环绕通知(@Around):内部执行方法,可自定义在方法执行的前后操作。
- 前置通知(@Before):在方法执行前执行。
- 后置通知(@After):在方法执行后执行。
- 返回通知(@AfterReturning):在方法返回后执行。
- 异常通知(@AfterThrowing):在方法抛出异常后执行。
- 连接点(JoinPoint):就是那些被切入点选中的方法。这些方法会被增强处理。
对于各种通知的方法、注解等没有什么特别的操作,具体使用会在后面举例。而切入点是选择对哪些方法生效的定义,那怎么知道它选择的是哪些方法呢?因为有多种匹配方式。
表达式类型 | 功能 |
---|---|
execution() | 匹配方法,最全的一个 |
args() | 匹配入参类型 |
@args() | 匹配入参类型上的注解 |
@annotation() | 匹配方法上的注解 |
within() | 匹配类路径 |
@within() | 匹配类上的注解 |
this() | 匹配类路径,实际上AOP代理的类 |
target() | 匹配类路径,目标类 |
@target() | 匹配类上的注解 |
用的比较多的是execution()
和@annotation
-
execution(修饰符 返回值类型 方法名(参数)异常)
语法参数 描述 修饰符 可选,如public,protected,写在返回值前,任意修饰符填 *
号就可以返回值类型 必选
,可以使用*
来代表任意返回值方法名 必选
,可以用*
来代表任意方法参数 () 代表是没有参数,
(…)代表是匹配任意数量,任意类型的参数,当然也可以指定类型的参数进行匹配,如要接受一个String类型的参数,则
(java.lang.String), 任意数量的String类型参数:
(java.lang.String…)异常 可选,语法: throws 异常
,异常是完整带包名,可以是多个,用逗号分隔看几个常用的写法
// 所有方法 execution(* *..*(..)) // 指定参数,即入参本身的类型,不能放其接口、父类 execution(* *..*(java.lang.String, java.lang.String) // 指定方法前缀 execution(* *..*.prefix*(..)) // 指定方法后缀 execution(* *..*.*suffix(..)) // 组合,增强所有方法,但是去掉指定前缀和指定后缀的方法 execution(* *..*(..)) && (!execution(* *..prefix*(..)) || !execution(* *..*suffix(..)))
-
@annotation()
匹配方法上的注解,括号内写注解定义的全路径,所有加了此注解的方法都会被增强。
// 增强被指定注解修饰的方法(所有加了@TestAspect注解的都会被) @annotation(com.banmoon.test.annotation.TestAspect) // 指定前缀的注解修饰的方法 @annotation(com.banmoon.test.annotation.Prefix*) // 指定后缀的注解修饰的方法 @annotation(com.banmoon.test.annotation.*Suffix)
3 Springboot中使用AOP
-
引入依赖
其实主要起作用的依赖是第二个,但现在
spring-boot-starter-web
启动依赖中已经包含AOP依赖,所以只引入第一个也可。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>
-
定义一个注解
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Auth {}
-
创建一个切面类
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method;@Aspect @Component public class AuthAspect {/*** 定义了一个切点* 这里的路径填自定义注解的全路径*/@Pointcut("@annotation(com.zz.business.annotations.Auth)")public void authCut() {}@Before("authCut()")public void cutProcess(JoinPoint joinPoint) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();System.out.println("注解方式AOP开始拦截, 当前拦截的方法名: " + method.getName());}@After("authCut()")public void after(JoinPoint joinPoint) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();System.out.println("注解方式AOP执行的方法 :" + method.getName() + " 执行完了");}@Around("authCut()")public Object testCutAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("注解方式AOP拦截开始进入环绕通知.......");Object proceed = joinPoint.proceed();System.out.println("准备退出环绕......");return proceed;}/*** returning属性指定连接点方法返回的结果放置在result变量中** @param joinPoint 连接点* @param result 返回结果*/@AfterReturning(value = "authCut()", returning = "result")public void afterReturn(JoinPoint joinPoint, Object result) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();System.out.println("注解方式AOP拦截的方法执行成功, 进入返回通知拦截, 方法名为: " + method.getName() + ", 返回结果为: " + result.toString());}@AfterThrowing(value = "authCut()", throwing = "e")public void afterThrow(JoinPoint joinPoint, Exception e) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();System.out.println("注解方式AOP进入方法异常拦截, 方法名为: " + method.getName() + ", 异常信息为: " + e.getMessage());} }
可以看到先是定义了一个切点
authCut
,之后前置通知、后置通知、环绕通知等都是绑在这个切点
上,在通过切点和指定方法连接起来。 -
连接点方法
该方法加了上面自定义的注解
@Auth
@RestController @RequestMapping("/company") @RefreshScope public class CompanyController { @GetMapping("/aopTest")@Authpublic AjaxResult aopTest(@RequestParam String name){//远程调用System.out.println("正在执行接口name" + name);return AjaxResult.success("执行成功" + name);} }
执行后的流程如下图
可以看到环绕通知是包在最外侧的。
4 AOP原理
AOP的代理使用 JDK 动态代理和 CGLIB 代理来实现,默认如果目标对象是接口,则使用 JDK 动态代理,否则使用 CGLIB 来生成代理类。
动态代理:程序执行过程中,使用JDK的反射机制,创建代理类对象,并动态的指定要代理目标类。动态代理涉及到的三个类:
-
InvocationHandler接口:处理器,负责完调用目标方法(就是被代理类中的方法),并增强功能;通过代理类对象执行目标接口中的方法,会把方法的调用分派给调用处理器(InvocationHandler)的实现类,执行实现类中的invoke()方法,我们需要把在该invoke()方法中实现调用目标类的目标方法;
-
Proxy 类:通过 JDK 的 java.lang.reflect.Proxy 类实现动态代理 ,使用其静态方法 newProxyInstance(),依据目标对象(被代理类的对象)、业务接口及调用处理器三者,自动生成一个动态代理对象。
-
Method 类:Method 是实例化的对象,有一个方法叫
invoke()
,该方法在反射中就是用来执行反射对象的方法的。
在上述代码中也可以看到,就是拿到了Method类型的对象,可以调用invoke()
方法执行,除此之外还可以获取方法的各种属性:getAnnotation-获取注解
、getName()-方法名字
等等。
5 应用场景
AOP在项目中通常用作一些共通的工作
- 接口方法日志的收集
- 接口方法的权限校验
- 前后对出入参的修改,先查缓存这种需求
相关文章:

SpringBoot使用AOP详解
目录 1 AOP是什么2 AOP概念3 Springboot中使用AOP4 AOP原理5 应用场景 1 AOP是什么 AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续&…...
【Qt】QGroundControl入门1:介绍
1、简介 1.1 QGroundControl QGroundControl是一款开源的无人机地面控制站软件,依赖Qt库,简称QGC。 QGroundControl为任何支持 MAVLink协议 的无人机提供完整的飞行控制和任务规划。QGroundControl为 PX4 和 ArduPilot 驱动的无人机提供驱动配置。 源码:https://github.co…...

第36章_瑞萨MCU零基础入门系列教程之步进电机控制实验
本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总: ht…...
198.打家劫舍,213.打家劫舍II,337.打家劫舍III
代码随想录训练营第48天|198.打家劫舍,213.打家劫舍II,337.打家劫舍III 198.打家劫舍文章思路代码 213.打家劫舍III文章思路代码 337.打家劫舍III文章思路代码 总结 198.打家劫舍 文章 代码随想录|0198.打家劫舍 思路 d p [ i ] M a x ( d p [ i − …...

msvcp140.dll是什么东西,如何解决msvcp140.dll丢失的问题的方法分享
在现代生活中,电脑已经成为我们工作、学习和娱乐的重要工具。然而,电脑问题的出现往往会给我们的生活带来不便。其中,"msvcp140.dll丢失"是一个常见的电脑问题。本文将详细介绍这个问题的原因和解决方法,帮助大家更好地…...
音视频 SDL vs2017配置
一、首先我把SDL放在了C盘根目录下 二、新建空项目 三、添加main.cpp //main.cpp #include<iostream> #include <SDL.h>int main(int argc, char* argv[]) // main函数头必须这样写,因为SDL把main定义成了宏 {SDL_Delay(3000); // 让窗口在屏幕上保持…...

前端面试要点
0914 JScript深拷贝和浅拷贝(js解构赋值算哪个?) 深拷贝和浅拷贝 回流和重绘 回流和重绘 webpack打包流程 Webpack打包 虚拟DOM 虚拟DOM git合并分支 git合并分支 CSS盒子模型 CSS盒子模型 0911 WebPack分包 webpack分包 ts泛型 ts泛型 优化…...
shell字符串处理之字符串比较
引言 我们在使用shell编写脚本时,经常需要对字符串进行处理,如字符串大小比较、模式匹配、替换、截断等。本文将梳理字符串比较中常见的用法。 字符串比较 1. 直接比较字符串 a$1 b$2 c"" # 等于 if [ $a "abc" ];thenecho $a …...

怎么获取别人店铺的商品呢?
jd.item_search_shop(获得店铺的所有商品) 为了进行电商平台 的API开发,首先我们需要做下面几件事情。 1)开发者注册一个账号 2)然后为每个JD应用注册一个应用程序键(App Key) 。 3)下载JDAPI的SDK并掌握基本的API…...

【数据结构】二叉树的链式结构
【数据结构】二叉树的链式存储结构 二叉树的存储结构 typedef int BTDataType; // 二叉树的结构 typedef struct BinaryTreeNode {BTDataType data; // 树的值struct BinaryTreeNode *left; // 左孩子struct BinaryTreeNode *right;// 右孩子 } BinaryTreeNode;二…...

模拟实现C语言--strlen函数
模拟实现C语言–strlen函数 模拟实现C语言--strlen函数一、strlen函数是什么?二、strlen函数的模拟实现2.1 计数器方式实现strlen函数2.2 不创建临时变量计数器方式实现strlen函数2.3 指针-指针方式实现strlen函数 三、strlen函数的返回类型 一、strlen函数是什么&a…...
Spring Boot + Vue的网上商城之物流系统实现
Spring Boot Vue的网上商城之物流系统实现 思路 当构建一个物流系统时,我们可以按照以下步骤进行: 设计数据模型:首先确定系统中需要存储的数据,例如物流公司信息、物流订单信息等。根据需求设计相应的数据模型,包括…...

释放数据价值这道难题,Smartbi V11有解
《未来简史》预言:数据将成为人们未来的信仰。 未来已来,将至已至。如今,数据所扮演的角色与作用超乎想象。从政府将数据要素列入生产要素之中,到数据驱动型业务场景涌现,企业与组织对于数据及其价值的认可度明显提升…...

Day_14 > 指针进阶(3)> bubble函数
目录 1.回顾回调函数 2.写一个bubble_sort函数 2.1认识一下qsort函数 编辑2.2写bubble_sort函数 今天我们继续深入学习指针 1.回顾回调函数 我们回顾一下之前学过的回调函数 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针(地址)…...

sql中怎么查books表下面的内容
要查询 books 表中的所有内容,你可以使用以下 SQL 语句: USE bookmanagement; -- 选择数据库 SELECT * FROM books; -- 查询books表中的所有内容如果你使用的是命令行界面 (mysql 客户端) 来操作数据库,可以直接在命令提示符中输入上述命令…...

Vulnhub系列靶机---HarryPotter-Aragog-1.0.2哈利波特系列靶机-1
文章目录 方式一信息收集主机发现端口扫描目录扫描wpscan工具 漏洞利用msf工具数据库权限用户权限root提权 方式二信息收集gobuster扫描wpscan扫描 漏洞利用POC 靶机文档:HarryPotter: Aragog (1.0.2) 下载地址:Download (Mirror) 方式一 信息收集 主机…...

.NET 8发布首个RC,比.NET 7的超级快更快
.NET 8 发布了首个 RC。据称 RC 阶段会发布两个版本,正式版将于 2023 年 11 月 14 日至 16 日在 .NET Conf 2023 上推出。.NET 8 是长期支持 (LTS) 版本,将会获得 3 年技术支持。 公告写道,此版本为 Android 和 WASM 引入了全新的 AOT 模式、…...

在 Substance Painter中自定义Shader
为什么要学习在Substance Painter中自定义Shader? 答:需要实现引擎与Substance Painter中的渲染效果一致,材质的配置也一致,所见即所得。 基础概述 首先在着色器设置这里,我们可以查看当前渲染使用的着色器 如果没有…...

【自学开发之旅】Flask-restful-Jinjia页面编写template-回顾(五)
restful是web编程里重要的概念 – 一种接口规范也是一种接口设计风格 设计接口: 要考虑:数据返回、接收数据的方式、url、方法 统一风格 rest–表现层状态转移 web–每一类数据–资源 资源通过http的动作来实现状态转移 GET、PUT、POST、DELETE path…...

input 的 placeholder 样式
::placeholder 伪元素 这个伪元素可以改变 input、textarea 占位文本的样式。 input::placeholder {color: green; }完整的兼容性写法: input {&::-webkit-input-placeholder, /* WebKit browsers*/ &:-moz-input-placeholder, /* Mozilla Firefox 4 to …...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...