Spring的AOP切面应用对【后台对接口增强】

news2024/12/25 16:27:23

目录

    • 📚简介:
    • 💨切面表达式:
    • 💭切面通知类型:
    • 🗺️创建项目演示:
      • 🎢创建项目:
      • 🎃添加依赖:
      • 💨编写切面类:
      • 🚀测试效果:
    • 🎉结束:

📚简介:

      我们写一个方法时如果每个接口都需要写一段固定的代码时,我们可以考虑使用切面(AOP)对方法进行增强,这些增强的方法称为连接点。好比我现在有个接口是用于提交数据或者对数据进行修改,这个时候如果发现数据有问题是不是应该进行排查,如果是直接打印日志的方式不是开发的同学就没办法判断为什么会产生错误数据,一般后台系统都有张表是用于记录用户操作数据的,这样我们就可以通过提交的数据进行排查为什么会产生错误数据,还有一个就是对数据进行操作产生问题追究职责的看是那个后台用户进行操作的。如果是按照之前的方式就是在对应的接口写保存日志的代码,代码就会变得重复且无意义,当保存记录添加新字段时我们又得到每一个接口上进行修改添加。
      当使用切面以后我们只需要定义一个切面类对一些方法进行统一处理。切面可以通过添加execution表达式进行对指定包下某个类某个方法进行增强。

💨切面表达式:

execution( [权限修饰符] [返回类型] [方法名称] ([参数列表]))

如:对com.itmei.service.CsService.update()方法进行增强
表达式如下:

execution(*  com.itmei.service.CsService.update(..))

如:对com.itmei.service.CsService下的所有方法进行增强
表达式如下:

execution(*  com.itmei.service.CsService.*(..))

如:对com.itmei.service包下的所有类方法进行增强
表达式如下:

execution(*  com.itmei.service.*.*(..))

💭切面通知类型:

  • 前置通知——@Before() (在调用被增强的方法前会调用该方法)
  • 后置通知——@AfterReturning() (当方法运行完成后会调用该方法)
  • 环绕通知——@Around
  • 异常通知——@AfterThrowing()
  • 最终通知——@After()(相当于finally)

后面代码中演示就比较好理解

🗺️创建项目演示:

🎢创建项目:

    创建一个SpringBoot项目如果不知道然后创建可以点击查看
只需要看这个章节就可以创建好SpringBoot项目,我这里就不过多进行介绍如何创建项目。

在这里插入图片描述

🎃添加依赖:

在pom.xml中添加依赖

   <!--添加SpringBoot的AOP依赖-->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
   </dependency>

在这里插入图片描述

添加对应的包和类:

在这里插入图片描述

需要增强的类

在这里插入图片描述

💨编写切面类:

创建切面类:



/**
 * @Author Itmei
 * @Date 2022/12/18 10:47
 * @Version 1.0
 * AOP类
 */
@SuppressWarnings("AlibabaCommentsMustBeJavadocFormat")
@Component
@Aspect //切面注解
@Order(10) // 若有多个切面类,可以用Order注解决定不同类中的切面的执行顺序值越小越先执行
public class CommonAop {
    //标识切入点的特征
    @Pointcut(value = "execution(*  com.itmei.springaopdemo.service.impl.CsServiceImpl.update(..))")
    public void pointCut(){}

    //前置通知
    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint){
        System.out.println("前置通知:处理查询该用户那些权限");
        System.out.println("  --方法的请求参数:"+Arrays.toString(joinPoint.getArgs()));
    }




    /**
     * 后置通知(@After):当被增强的方法结束后会调用该通知
     * @param joinPoint
     */
    @After(value = "pointCut()")
    public void after(JoinPoint joinPoint){
        System.out.println("后置通知:当被增强的方法结束后会调用该通知");
    }

    /**
     * 返回通知(@AfterReturning):当被增强的方法 成功执行之后调用通知
     * @param joinPoint
     * @param jsonResult
     */
    @AfterReturning(value = "pointCut()",returning = "jsonResult")
    public void afterReturning(JoinPoint joinPoint,Object jsonResult){
        System.out.println("返回通知:当被增强的方法 成功执行之后调用通知");
    }


    /**
     * 异常通知(afterThrowing) 当被增强的方法 出现异常之后调用通知
     * @param joinPoint
     */
    @AfterThrowing(value = "pointCut()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint,Exception e){
        System.out.println("异常通知:当被增强的方法 出现异常之后调用通知");
        System.out.println("  --"+e.getMessage());
    }

    /**
     * 环绕通知 使用环绕通知后可以不使用Before和after通知
     * proceedingJoinPoint.proceed();的作用是让目标方法执行,@Around = @Before + 方法执行 + @After
     */
    @Around(value = "pointCut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        //这里写Before通知的代码
        System.out.println("环绕通知:Before");
        try {
            proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            System.out.println("环绕通知:报错信息"+throwable.getMessage());
        }
        //这里写after通知的代码
        System.out.println("环绕通知:after");
    }


}


🚀测试效果:

@SpringBootTest
class SpringAopDemoApplicationTests {

    @Resource
    private CsService csService;

    @Test
    void contextLoads() {
        csService.update("123","itmei");
    }

}

在这里插入图片描述

运行结果:

在这里插入图片描述

由此可以得出:
无异常:@Around(proceed()之前的部分) → @Before → 方法执行 →@AfterReturning →@After →@Around(proceed()之后的部分

在需要增强的方法添加报错:

在这里插入图片描述

运行效果:

在这里插入图片描述

由此可以得出:
有异常:@Around(proceed(之前的部分)) → @Before→ 方法执行 → @AfterThrowing→ @After →@Around(异常捕获的代码) →@Around(proceed(之后的部分))

🎉结束:

那么我们就可以把,进入日志的代码写在前置通知或者后置通知里面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端显示分页详解

我们在浏览页面的时候&#xff0c;是不是经常看到网页经常是以页面的形式给我们展现出来的&#xff0c;我们以淘宝的页面为例&#xff08;如下图&#xff09;&#xff0c;那这样按照页面呈现有什么好处呢&#xff1f;这篇文章让我们来深入探究了解这其中的奥秘。 优点&#xff…

泛型自动装箱

目录 前言 泛型 1.泛型的目的 2.泛型存在的意义和注意事项&#xff1a; 3.擦除机制 4.泛型的边界 5.泛型方法&#xff1a; 包装类&#xff1a; 前言 只要知道《》是啥意思&#xff0c;其他了解即可 泛型的上界 通配符简单知道就行 泛型 1.泛型的目的 指定当前的容器&am…

【JVM】浅析程序计数器与虚拟机栈

文章目录1. 程序计数器2. 虚拟机栈3. 栈内存溢出1. 程序计数器 Program Counter Register 程序计数器&#xff08;寄存器&#xff09; 程序计数器的作用是什么&#xff1f; 是记录下一条JVM指令的执行地址行号 程序计数器有什么特点&#xff1f; 线程私有的不会存在内存溢出 …

ADI Blackfin DSP处理器-BF533的开发详解59:DSP控制ADXL345三轴加速度传感器的应用2(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 MEMS三轴加速度传感器 我做了一个三轴加速度传感器的子卡&#xff0c;插在这个板子上&#xff0c;然后写了一些有意思的应用程序。 硬件实现原理…

Linux——定制Linux

Linux启动流程 首先&#xff0c;Linux要通过自检&#xff0c;检查硬件设备有没有故障如果有多块启动盘的话&#xff0c;需要在BIOS选择启动磁盘启动MBR中的bootloader引导程序加载内核文件执行所有进程的父进程、老祖宗systemd欢迎界面 加载内核文件的关键文件 kernel文件&a…

C#调用Python脚本训练并生成AI模型(以Paddle框架为例)

目录一. IronPython语言移植1.1 IronPython安装1.2 示例代码1.3 运行结果1.4 特点二. C#调用Python文件打包dll2.1 步骤2.2 限制三. C#命令行调用.py文件执行3.1 代码3.3 运行结果3.4 特点四. C#调用Python可执行exe4.1 步骤4.1.1 使用pyinstaller打包python程序4.1.2 在c#中调…

入门:手动构建镜像

前面我们已经了解了Docker镜像的结构&#xff0c;实际上所有常用的应用程序都有对应的镜像&#xff0c;我们只需要下载这些镜像然后就可以使用了&#xff0c;而不需要自己去手动安装&#xff0c;顶多需要进行一些特别的配置。当然要是遇到某些冷门的应用&#xff0c;可能没有提…

【细胞分割】中值滤波+分水岭法细胞计数【含Matlab源码 640期】

⛄一、图像分割简介 理论知识参考&#xff1a;【基础教程】基于matlab图像处理图像分割【含Matlab源码 191期】 ⛄二、部分源代码 clear; close all; %------------------ %程序中定义图像变量说明 %Image->原图变量; %Image_BW->二值化图象; %Image_BW_medfilt->中…

【实时数仓】DWM层跳出明细计算之需求分析、读取数据、通过Flink的CEP完成跳出判断、写回kafka、测试

文章目录一 DWM层-跳出明细计算1 需求分析与思路&#xff08;1&#xff09;什么是跳出&#xff08;2&#xff09;计算跳出行为的思路&#xff08;3&#xff09;实现思路2 读取数据&#xff08;1&#xff09;代码编写&#xff08;2&#xff09;测试3 通过Flink的CEP完成跳出判断…

【MATLAB100个实用小技巧】——数值分析(85-100)

文章目录前言系列文章85.86. 三次样条插值法87. NEWTON 插值88. hermite 插值89. newton 形式的 hermite 插值90. 平方根法91. gauss 消去法92. 三角分解法93. jacobi 迭代法94. gauss 迭代法95. sor 迭代法96. 最速下降法97. 共额梯度法98. newton 迭代法99. broyden 迭代法10…

前端媒体查询@media示例详解和calc()函数的使用

媒体查询media media 可以针对不同的屏幕尺寸设置不同的样式&#xff0c;特别是如果需要设置设计响应式的页面&#xff0c;media 是非常有用的。当重置浏览器大小的过程中&#xff0c;页面也会根据浏览器的宽度和高度重新渲染页面。 eg&#xff1a;如果文档宽度小于 500 像素…

pytorch 自编码器实现图像的降噪

自编码器 自动编码器是一种无监督的深度学习算法&#xff0c;它学习输入数据的编码表示&#xff0c;然后重新构造与输出相同的输入。它由编码器和解码器两个网络组成。编码器将高维输入压缩成低维潜在(也称为潜在代码或编码空间) &#xff0c;以从中提取最相关的信息&#xff…

SpringCloud之Hystrix

复杂分布式体系结构中的应用程序有数十个依赖关系&#xff0c;每个依赖关系在某些时候将不可避免失败&#xff01; 服务雪崩 多个微服务之间调用的时候&#xff0c;假设微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其他的微服务&#xff0c;这就是所谓的“…

HttpRunner3.x 安装与使用

HttpRunner3.x 安装与使用HttpRunner3.x 安装与使用安装使用运行脚手架项目方式一&#xff1a;录制生成用例步骤1&#xff1a;导出har文件步骤2&#xff1a;转化成测试用例文件har2casehmake步骤3&#xff1a;执行测试用例方式二&#xff1a;手工编写测试用例HttpRunner3.x 安装…

Jenkins自动部署springboot的Docker镜像,解决Status [1]问题

Jenkins凡是要指定路径的命令&#xff0c;一定要写绝对路径&#xff0c;不能写相对路径&#xff01;不要以为配置了Remote directory&#xff0c;那么命令就会在Remote directory下执行&#xff01;这种想法是错误的&#xff01;&#xff01;&#xff01; 《jenkins自动化发布到…

机器学习实战教程(五):朴素贝叶斯实战篇

一、前言 上篇文章机器学习实战教程&#xff08;四&#xff09;&#xff1a;朴素贝叶斯基础篇_M_Q_T的博客-CSDN博客讲解了朴素贝叶斯的基础知识。本篇文章将在此基础上进行扩展&#xff0c;你将看到以下内容&#xff1a; 拉普拉斯平滑垃圾邮件过滤(Python3)新浪新闻分类(skle…

毕业设计 - 基于Java的敬老院管理系统设计与实现【源码+论文】

文章目录前言一、项目设计1. 模块设计系统的主要功能性需求2. 实现效果二、部分源码项目源码前言 今天学长向大家分享一个 java web项目: 基于Java的敬老院管理系统设计与实现 一、项目设计 1. 模块设计 站在护工角度来看&#xff0c;他们迫切希望&#xff0c;在运用该系统…

【Flink】Flink Starting Offset 启动消费位置 指定时间消费

文章目录 1.概述2.测试3.源码1.概述 首先参考文章:【Flink】Flink 1.14.0 全新的 Kafka Connector Kafka Source 能够通过指定 OffsetsInitializer来消费从不同偏移量开始的消息。内置的初始值设定项包括: KafkaSource.builder()// Start from committed offset of the co…

【YOLOv7-环境搭建③】PyCharm安装和环境、解释器配置

下载链接&#xff1a; 来源&#xff1a;&#xff08;博主&#xff09;唐三. 链接:https://pan.baidu.com/s/1y6s_EScOqvraFcx7iPSy1g 提取码:m1oa 安装&#xff1a; 以管理员身份打开安装完成后&#xff0c;打开软件到达以下界面&#xff0c;框框全选到达以下界面&#xf…

【指纹识别】指纹识别匹配门禁系统【含GUI Matlab源码 587期】

⛄一、指纹识别简介 1 指纹识别的引入和原理 1.1 指纹的基本知识 指纹&#xff0c;由于其具有终身不变性、唯一性和方便性&#xff0c;已几乎成为生物特征识别的代名词。指纹是指人的手指末端正面皮肤上凸凹不平产生的纹线。纹线有规律的排列形成不同的纹型。纹线的起点、终点…