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

【Spring Boot】Spring AOP中的环绕通知

目录

    • 一、什么是AOP?
    • 二、AOP 的环绕通知
      • 2.1 切点以及切点表达式
      • 2.2 连接点
      • 2.3 通知(Advice)
      • 2.4 切面(Aspect)
      • 2.5 不同通知类型的区别
        • 2.5.1 正常情况下
        • 2.5.2异常情况下
      • 2.6 统一管理切点@PointCut

一、什么是AOP?

Aspect Oriented Programming(面向切面编程)

AOP是Spring框架的第⼆⼤核⼼(第⼀⼤核⼼是IoC)

AOP是一种思想,是对某一类事情的集中处理。
其中在下面的学习中我们会学习到拦截器、统一异常处理,统一结果处理等,这些都是运用了AOP的统一思想来实现的。

拦截器实现AOP思想作用的维度是前端对后端进行的一次请求和一次响应,主要是检索前端传来的URL,如果检索后返回True,则可以进入Controller开始执行代码,如果返回的为False,则表示失败,直接被拦截在外面,无法执行代码。

统一结果处理则是使用注解@ControllerAdvice(通知类注解),实现ResponseBodyAdvice接口,对响应的结果进行统一处理,对齐进行统一的包装后响应,其中如果数据类型为String类型的话要进行特殊处理,使用ObjectMapper的方法将String格式转为Json格式再次响应。

统一异常处理也是使用注解@ControllerAdvice(通知类注解),以及在方法上使用@ExceptionHandler注解,在全部的程序中如果遇到运行时异常则会自动捕捉,进行抛出,注:编译时异常是写代码过程中出现的,不手动解决就无法运行程序。

接下来我们要学习的是运用了AOP思想,进行AOP的环绕处理

二、AOP 的环绕通知

2.1 切点以及切点表达式

切点=通知类型+切点表达式
切点表示了为该方法提供一组规则,来对程序进行功能增强

通知类型有以下5种:

@Around:环绕通知,此注解标注的通知方法在目标方法前,后都被执行
@Before:前置通知,此注解标注的通知方法在目标方法前被执行
@After:后置通知,此注解标注的通知方法在目标方法后被执行,⽆论是否有异常都会执行
@AfterReturning:返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
@AfterThrowing:异常后通知,此注解标注的通知方法发⽣异常后执行

如下图所示:
在这里插入图片描述
在该方法上的@Around,表示的是环绕处理,是一种通知类型
其后面的execution(* com.example.demo.controller..(…)) 表示的是该通知类型作用的范围,是切点表达式

2.2 连接点

满足切点表达式规则的方法就是连接点
在这里插入图片描述
在该图中,public recordTime方法就是连接点

2.3 通知(Advice)

通知就是具体要做的内容,简单来说就是方法内执行的代码内容

如图所示:
在这里插入图片描述
该图中标红的位置就是通知内容,在AOP面向切面编程当中,我们把这部分重复的代码逻辑抽取出来单独定义,这部分代码就是通知的内容

2.4 切面(Aspect)

首先使用注解@Aspect来表示该类是一个切面类
然后使用不同的通知类型进行处理,如图表示的是环绕通知类型
在处理过程中ProceedingJoinPoint.proceed()让原始方法执行
在这里插入图片描述
切面(Aspect)=切点(Pointcut)+通知(Advice)
以下代码表示一个完整的切面类:

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;@Slf4j
@Aspect
@Componentpublic class TimeAspect {/*** 记录方法耗时*/@Around("execution(* com.example.demo.controller.*.*(..))")public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {//记录方法执行开始时间long begin = System.currentTimeMillis();//执行原始方法Object result = pjp.proceed();//记录方法执行结束时间long end = System.currentTimeMillis();//记录方法执行耗时log.info(pjp.getSignature() + "执行耗时: {}ms", end - begin);return result;}
}

2.5 不同通知类型的区别

2.5.1 正常情况下

环绕通知 @Around 标识的通知方法包含两部分,⼀个"前置逻辑",⼀个"后置逻辑".其
中"前置逻辑"会先于 @Before 标识的通知方法执行,"后置逻辑"会晚于 @After 标识的通知方法执行
在这里插入图片描述

2.5.2异常情况下

程序发⽣异常的情况下:
• @AfterReturning 标识的通知方法不会执行, @AfterThrowing 标识的通知方法执行了
• @Around 环绕通知中原始方法调⽤时有异常,通知中的环绕后的代码逻辑也不会在执行了(因为
原始方法调⽤出异常了)
在这里插入图片描述
注意事项:
• @Around 环绕通知需要调⽤ ProceedingJoinPoint.proceed() 来让原始方法执行,其他
通知不需要考虑目标方法执行.
• @Around 环绕通知方法的返回值,必须指定为Object,来接收原始方法的返回值,否则原始方法执
行完毕,是获取不到返回值的.
• ⼀个切面类可以有多个切点

2.6 统一管理切点@PointCut

统一管理切点就是对于复杂的切点表达式进行提取,然后用@PointCut注解方法进行单独声明,再本类下面的程序中如果用到该切点表达式,则直接使用注解后的方法即可,如果在其他类中使用该声明过后的切点表达式则需要使用全路径限定名+该方法即可

本类使用注解后的切点表达式代码如下:

@Slf4j
@Aspect
@Componentpublic class AspectDemo {//定义切点(公共的切点表达式)@Pointcut("execution(* com.example.demo.controller.*.*(..))")private void pt(){}//前置通知@Before("pt()")public void doBefore() {//...代码省略}//后置通知@After("pt()")public void doAfter() {//...代码省略}//返回后通知@AfterReturning("pt()")public void doAfterReturning() {//...代码省略}//抛出异常后通知@AfterThrowing("pt()")public void doAfterThrowing() {//...代码省略}//添加环绕通知@Around("pt()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {//...代码省略}
}

在其他类中调用该切点表达式代码如下:

@Slf4j
@Aspect
@Componentpublic class AspectDemo2 {//前置通知@Before("com.example.demo.aspect.AspectDemo.pt()")public void doBefore() {log.info("执行 AspectDemo2 -> Before 方法");}}```当切点定义使⽤private修饰时,仅能在当前切面类中使⽤,当其他切面类也要使⽤当前切点定义时,就需要把private改为public.引⽤方式为:全限定类名.方法名()
### 2.7     切面优先级@Order
在切面类中会有多个切点同时匹配成功,那么该如何进行执行顺序呢?
应该使用注解@Order(数字)来表示优先级顺序@Order注解标识的切面类,执行顺序如下:@Before 通知:数字越⼩先执行
• @After 通知:数字越⼤先执行@Order 控制切面的优先级,先执行优先级较⾼的切面,再执行优先级较低的切面,最终执行目标方法.

相关文章:

【Spring Boot】Spring AOP中的环绕通知

目录 一、什么是AOP?二、AOP 的环绕通知2.1 切点以及切点表达式2.2 连接点2.3 通知(Advice)2.4 切面(Aspect)2.5 不同通知类型的区别2.5.1 正常情况下2.5.2异常情况下 2.6 统一管理切点PointCut 一、什么是AOP? Aspect Oriented Programming&#xff…...

docker部署前端,配置域名和ssl

之前使用80端口部署前端项目后,可以使用IP端口号在公网访问到部署的项目。 进行ICP域名备案后,可以通过域名解析将IP套壳,访问域名直接访问到部署的项目~ 如果使用http协议可以很容易实现这个需求,对nginx.conf文件进行修改&#…...

初学Spring之 IOC 控制反转

Spring 是一个轻量级的控制反转&#xff08;IOC&#xff09;和面向切面编程&#xff08;AOP&#xff09;的框架 导入 jar 包&#xff1a;spring-webmvc、spring-jdbc <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc&…...

rpc的仅有通信的功能,在网断的情况下,比网通情况下,内存增长会是什么原因

RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;主要负责在分布式系统中透明地调用远程服务&#xff0c;就像调用本地函数一样。它封装了网络通信的细节&#xff0c;使得开发者可以专注于业务逻辑而非底层通信协议。RPC通信通常包括序列化、网络传输…...

从零开始:如何设计一个现代化聊天系统

写在前面: 此博客内容已经同步到我的博客网站,如需要获得更优的阅读体验请前往https://mainjaylai.github.io/Blog/blog/system/chat-system 在当今数字化时代,聊天系统已成为我们日常生活和工作中不可或缺的一部分。从个人交流到团队协作,从客户服务到社交网络,聊天应用…...

香橙派OrangePi AIpro初体验:当小白拿到一块开发板第一时间会做什么?

文章目录 香橙派OrangePi AIpro初体验&#xff1a;当小白拿到一块高性能AI开发板第一时间会做什么前言一、香橙派OrangePi AIpro概述1.简介2.引脚图开箱图片 二、使用体验1.基础操作2.软件工具分析 三、香橙派OrangePi AIpro.测试Demo1.测试Demo1&#xff1a;录音和播音(USB接口…...

【C语言内存函数】

目录 1.memcpy 使用 模拟实现 2.memmove 使用 模拟实现 3.memset 使用 4.memcmp 使用 1.memcpy 使用 void * memcpy ( void * destination, const void * source, size_t num );目的地址 源地址 字节数 destination&#xff1a;指向要复制内…...

Mysql部署MHA高可用

部署前准备&#xff1a; mysql-8.0.27下载地址&#xff1a;https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.27-1.el7.x86_64.rpm-bundle.tar mha-manager下载地址&#xff1a;https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-mana…...

【算法学习】射线法判断点在多边形内外(C#)以及确定内外两点连线与边界的交点

1.前言&#xff1a; 在GIS开发中&#xff0c;经常会遇到确定一个坐标点是否在一块区域的内部这一问题。 如果这个问题不是一个单纯的数学问题&#xff0c;例如&#xff1a;在判断DEM、二维图像像素点、3D点云点等含有自身特征信息的这些点是否在一个区域范围内部的时候&#x…...

SQL语句(DML)

DML英文全称是Data Manipulation Language&#xff08;数据操作语言&#xff09;&#xff0c;用来对数据库中表的数据记录进行增删改等操作 DML-添加数据 insert into employee(id, workno, name, gender, age, idcard) values (1,1,Itcast,男,10,123456789012345678);select *…...

uniapp小程序打开地图导航

uniapp uni.getLocation({type: gcj02, //返回可以用于uni.openLocation的经纬度success: function (res) {const latitude res.latitude;const longitude res.longitude;uni.openLocation({latitude: latitude,longitude: longitude,success: function () {console.log(suc…...

webstorm格式化或保存时 vue3引入的组件被删除了

解决办法 保存时设置 格式化设置...

Java时间转换

一、线程不安全 Date date new Date(); SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String prefix dateFormat.format(date);二、线程安全,建议使用 String t1 LocalDateTime.now().format(DateTimeFormatter.ofPattern("y…...

Spring Boot与WebFlux的实战案例

Spring Boot与WebFlux的实战案例 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将探讨如何利用Spring Boot和WebFlux构建响应式应用的实战…...

vue3引入本地静态资源图片

一、单张图片引入 import imgXX from /assets/images/xx.png二、多张图片引入 说明&#xff1a;import.meta.url 是一个 ESM 的原生功能&#xff0c;会暴露当前模块的 URL。将它与原生的 URL 构造器 组合使用 注意&#xff1a;填写自己项目图片存放的路径 /** vite的特殊性…...

git 禁止dev合并到任何其他分支

创建 pre-merge-commit 钩子 导航到 Git 仓库的钩子目录&#xff1a; cd /path/to/your/repo/.git/hooks创建或编辑 pre-merge-commit 钩子&#xff1a; 也可以通过指令创建 nano pre-merge-commit在钩子文件中添加以下代码&#xff1a; #!/bin/sh# 获取当前分支名称 curr…...

第二节:如何使用thymeleaf渲染html(自学Spring boot 3.x的第一天)

大家好&#xff0c;我是网创有方&#xff0c;今天来学习如何使用thymeleaf渲染html。该模板运用不广泛&#xff0c;所以本节内容了解既可。 第一步&#xff1a;创建html文件。 在模板templates目录下创建一个html文件。 编写代码如下&#xff1a; <!DOCTYPE html> <…...

计算机相关术语科普之什么叫网关(Gateway)

网关&#xff08;Gateway&#xff09;是一个在计算机网络中起到关键作用的设备或系统&#xff0c;它扮演着网络间连接器或协议转换器的角色。 一、定义与功能 1&#xff09;定义&#xff1a; 网关是在不同网络之间实现互连的复杂设备&#xff0c;仅用于两个高层协议不同的网…...

B站网页部分API

https://www.bilibili.com/ 数据结构 mid: 用户id name: 用户名 face: 用户头像url noface.jpg为默认头像 sign&#xff1a; 签名level: b站等级 coins: b站硬币粉丝 https://api.bilibili.com/x/relation/fans?vmid{mid}&pn{pn}&ps{limit}&orderdesc&…...

使用Spring Boot和Spring Security保护你的应用

使用Spring Boot和Spring Security保护你的应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨如何利用Spring Boot和Spring Security来保护…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...