SpringBoot使用AOP详解

news2024/10/5 14:03:56

目录

  • 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

  1. 引入依赖

    其实主要起作用的依赖是第二个,但现在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>
    
  2. 定义一个注解

    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 {
    
    }
    
  3. 创建一个切面类

    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,之后前置通知、后置通知、环绕通知等都是绑在这个切点上,在通过切点和指定方法连接起来。

  4. 连接点方法

    该方法加了上面自定义的注解@Auth

    @RestController
    @RequestMapping("/company")
    @RefreshScope
    public class CompanyController {    
    	@GetMapping("/aopTest")
        @Auth
        public 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在项目中通常用作一些共通的工作

  • 接口方法日志的收集
  • 接口方法的权限校验
  • 前后对出入参的修改,先查缓存这种需求

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

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

相关文章

【适用于电力系统和音频系统】计算信号的总谐波失真 (THD)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Sequential Recommendation with Graph Neural Networks

Sequential Recommendation with Graph Neural Networks 文章目录 1. 背景2. 模型2.1 Interest Graph Construction2.1.1 Raw graph construction2.1.2 Node similarity metric learning2.1.3 Graph sparsification via &#x1d700;-sparseness 2.2 Interest-fusion Graph C…

线性代数的本质(一)——向量空间

文章目录 向量空间向量及其性质基与维数向量的坐标运算 《线性代数的本质》 - 3blue1brown 高中数学A版选修4-2 矩阵与变换 《线性代数及其应用》(第五版) 《高等代数简明教程》- 蓝以中 向量空间 In the beginning Grant created the space. And Grant said, Let there be vec…

一文了解气象观测站是什么?

一、气象观测站的定义 气象观测站是一种专门负责观测、记录气象数据的设施&#xff0c;包括风向、风速、温度、湿度、气压、降水量等多个气象要素。这些数据不仅对科研和预报具有重要意义&#xff0c;还对我们的日常生活有着极大的影响。 二、气象观测站的种类 气象观测站根…

Vue3+Ts中使用Jquery

1、安装jquery&#xff1a;npm i jquery --save 2、在vue.config.js文件中添加如下代码&#xff1a; const { defineConfig } require(vue/cli-service) const webpack require(webpack)module.exports defineConfig({configureWebpack: {plugins: [// 配置jQuerynew webp…

蓝桥杯打卡Day9

文章目录 直角三角形最长平衡串 一、直角三角形IO链接 本题思路:本题就是利用欧几里得距离求解即可。 #include <bits/stdc.h>int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int T;std::cin>>T;while(T--){int x…

一键搭建免费eXtplorer在线文件管理器,远程登录实现文件随身存储

文章目录 1. 前言2. eXtplorer网站搭建2.1 eXtplorer下载和安装2.2 eXtplorer网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1. 前言 通过互联网传输文件&#xff0c;是互联网最重要的应用之一&#xff0c;无论是…

利用红黑树封装map和set

目录 一、正向迭代器1.1 operator1.2 operator--1.3 参考代码 二、反向迭代器三、封装set四、封装map五、底层红黑树的实现 一、正向迭代器 我们之前vector&#xff0c;list这些都是容器的迭代器都是简单的指针或者_node_node->next这样的&#xff0c;那是因为它们要么是连…

数据可视化:揭示隐藏信息的强大工具

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 引言 数据可视化是将数…

WebGL透视投影

目录 透视投影 透视投影可视空间 可视空间构造效果图 Matrix4.setPerspective&#xff08;&#xff09; 三角形与可视化空间的相对位置 示例代码 代码详解 示例效果 投影矩阵的作用 透视投影矩阵对物体进行了两次变换 透视投影变换示意图 透视投影 在透视投影下&…

华为云云耀云服务器L实例评测|拉取创建canal镜像配置相关参数 搭建canal连接MySQL数据库 spring项目应用canal初步

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;本篇博客介绍如何在华为云上部署canal的docker镜像&#xff0c;以及在spring项目中的初步应用。 其他相关的华为云云耀云服务器L实例评测文章列表如下&#xff1a; 初始化配置SSH连接 & 安装…

IntelliJ IDEA使用_常用快捷键(windows版)

文章目录 版本说明搜索操作层级关系查看光标选择代码定位代码操作Git操作编辑器操作 版本说明 当前的IntelliJ IDEA 的版本是2021.2.2&#xff08;下载IntelliJ IDEA&#xff09; ps&#xff1a;不同版本一些图标和设置位置可能会存在差异&#xff0c;但应该大部分都差不多。…

C++ PrimerPlus 复习 第四章 复合类型(上)

第一章 命令编译链接文件 make文件 第二章 进入c 第三章 处理数据 第四章 复合类型 &#xff08;上&#xff09; 文章目录 创建和使用数组&#xff1b;**声明语句中初始化数组元素。****使用大括号的初始化&#xff08;列表初始化&#xff09;** 字符串创建和使用C风格字符…

好用免费的链接转二维码

能把链接等转成二维码的形式 &#xff0c;并且是完全免费的 &#xff0c;超级好用&#xff1a;草料网址二维码生成器 https://cli.im/url?3f07d81d705e31db2dcde5ca2feeece8 测试了博客的链接转成了二维码 &#xff0c;很好用

(入门向)面向萌新的算法比赛入门指南

什么是算法 算法是指解决问题或完成特定任务的一系列明确指令或步骤集合。它是一个定义良好、逐步执行的操作序列&#xff0c;用于将输入转换为输出。算法可用于计算、数据处理、自动化控制、问题解决等各个领域。 算法通常由一系列简单的操作组成&#xff0c;这些操作可以是…

Java基于SpringBoot的逍遥大药房管理平台

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 大家好&#xff0c;我是程序员徐师兄、今天给大家谈谈基于android的app开发毕设题目&#xff0c;以及基于an…

GIS前端编程—视频展示

GIS前端编程—视频展示 视频展示1. 互联网公共地图服务开放平台2. 开源GIS服务平台 得益于互联网的快速发展&#xff0c;WebGIS发展迅猛&#xff0c;其开发工具与开发平台也呈现出百花齐放之势。目前&#xff0c;涌现出了大量的WebGIS二次开发产品。在互联网方向上&#xff0c;…

【Springboot】整合kafka

目录 安装zookeeperjdk安装zookeeper安装 安装kafka&#xff08;非集群&#xff09;springboot项目整合配置 安装zookeeper jdk安装 环境准备&#xff1a;CentOS7&#xff0c;jdk1.8 步骤如下&#xff1a; 下载自己需要的版本 这里使用的jdk1.8&#xff0c;获取链接如下 链接…

Maxwell 概述、安装、数据同步【一篇搞定】!

文章目录 什么是 Maxwell&#xff1f;Maxwell 输出格式Maxwell 工作原理Maxwell 安装Maxwell 历史数据同步Maxwell 增量数据同步 什么是 Maxwell&#xff1f; Maxwell 在大数据领域通常指的是一个用于数据同步和数据捕获的开源工具&#xff0c;由美国 Zendesk 开源&#xff0c…

千巡翼X1协调转弯功能

近年来&#xff0c;随着技术的飞速发展&#xff0c;无人机航测已成为现代测绘领域的一项重要应用。 无人机的出现极大地提高了航测的效率和精度&#xff0c;极大地减少了人力资源的投入。通过搭载各种高精度的航测仪器和传感器&#xff0c;无人机可以在短时间内完成大面积的航…