Spring AOP的介绍与实现

文章目录

  • Spring AOP
    • 1. Spring AOP概念
    • 2. Spring AOP的作用
    • 3.AOP的组成
    • 4. Spring AOP的实现
      • 4.1 添加Spring AOP依赖
      • 4.2 定义切面(创建切面类)
      • 4.3 定义切点(配置拦截规则)
        • 4.3.1 切点表达式语法
      • 4.4 定义通知的实现
    • 5. Spring AOP实现原理

Spring AOP

1. Spring AOP概念

AOP (Aspect Oriented Programming) :⾯向切⾯编程,是⼀种思想,它是对某⼀类事情的集中处理。

举个例子:
当我们进行用户登录权限的校验,在需要进行校验的页面中,我们都各⾃实现或调⽤⽤户验证的⽅法,有了 AOP 之后,我们只需要在某⼀处配置⼀下,需要登录校验的页面就可以自主实现,不再需要每个方法中都写相同的登录校验。

AOP与Spring AOP的关系和IoC和DI类似,AOP是一种思想,而Spring AOP是一个具体的框架对AOP的实现。

2. Spring AOP的作用

对于以上的登录校验例子来说,我们使用Spring AOP我们可以减少代码的重复,提高我们程序员开发的效率,在具体开发中它可以实现以下功能:

  1. 统一日志记录
  2. 统一方法执行时间统计
  3. 统一的返回格式设置
  4. 统一的异常处理
  5. 事务开启和提交
  6. 统一登录校验等

对于我们对象来说,AOP扩展了它的能力,在某个方面我们可以说AOP是OOP(面向对象编程)的补充和完善,它们都是一种思想。

3.AOP的组成

  • 切⾯(Aspect):切⾯(Aspect)由切点(Pointcut)和通知(Advice)组成,它既包含了横切逻辑的定义,也包括了连接点的定义。 在程序中就是一个处理某方面具体问题的类,类中包含很多方法,这些方法就是切点和通知。

  • 连接点(Join Point):应⽤执⾏过程中能够插⼊切⾯的⼀个点,这个点可以是方法调用时,抛出异常时或者修改字段时。切⾯代码可以利⽤这些点插⼊到应用的正常流程之中,并添加新的行为。它是可能会触发AOP的所有点(请求)。

  • 切点(Pointcut):切点是提供一组规则来匹配连接点,给满足规则的连接点添加通知。 切点就是用来进行主动拦截的规则(配置)然后触发AOP。

  • 通知(Advice):切面的工作被称为通知,定义了切⾯是什么,何时使用,描述了切⾯要完成的工作,还解决何时执行这个工作问题。也就是程序中被拦截请求触发的具体动作,在通知中的的具体业务代码。

通知的分类:使用注解可以实现

  • 前置通知:在执行目标方法之前执行的方法,@Before实现。比如我们要请求某页面要进行的登录检验相关方法,登录校验就是前置通知通过。请求页面的方法就是目标方法。
  • 后置通知:在执行目标方法之后执行的方法,通过@After实现。
  • 异常通知:在执行目标方法出现异常时执行的方法,通过@AfterThrowing实现。
  • 返回通知:目标方法执行了返回数据时(return)执行的通知,@AfterReturning实现。
  • 环绕通知:在目标方法执行的周期范围内(执行之前,执行中,执行后)都可以执行的。通过@Around实现。

4. Spring AOP的实现

4.1 添加Spring AOP依赖

首先创建一个Spring Boot项目,在创建过程中我们没有Spring AOP框架可选,需要在pom.xml文件中自己添加Spring AOP 依赖。
在这里插入图片描述

添加依赖,在Maven仓库中根据我们创建的spring boot项目添加以下依赖:
在这里插入图片描述

由于我使用的spring版本是2.7.13,所以我选用的版本也是2.7.13。

4.2 定义切面(创建切面类)

对于切面我使用的注解是@Component,让该类醉着框架启动。通过@Aspect表示该类是一个切面;

package com.example.demo_aop.component;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;/*** @author zq* @date 2023-07-19 20:04*/
@Component
@Aspect
public class UserAspect {}

4.3 定义切点(配置拦截规则)

定义切点通过@Poincut注解,使用Aspect的表达式语法;该方法是空方法只起到表示作用,指向后面多个对应的通知。

  //定义切点,使用Aspect的表达式语法
//    表示拦截该UserController下所有方法@Pointcut("execution(* com.example.demo_aop.controller.UserController.*(..))")public void poincut(){}

4.3.1 切点表达式语法

切点表达式由切点函数组成,其中 execution() 是最常⽤的切点函数,⽤来匹配⽅法,语法为:

execution(<修饰符><返回类型> <包.类.方法(参数)><异常>)

*号可以匹配任意字符,只匹配一个元素如包、类、方法、方法参数;…符号可以匹配任意字符,多个元素,在表示类时,需要与 星号联合使用;+号表示按照类型匹配指定类的所有类,必须跟在类名后面。如com.example.User+,就表示继承该类的所有子类和本身。

** 注意:**

  1. 修饰符和异常通常可以省略,返回值不能省略。
  2. 在我们上述代码中的表达式就省略了修饰符,用*号表示返回值类型。
  3. 返回值与包是两个东西所以加上了空格
  4. 在我们上述代码表达式省略了异常。括号中的点点表示匹配任意参数的方法。

4.4 定义通知的实现

以下实现前置通知和后置通知;注解中对应切点的方法名。

//    表示该通知针对该方法
//    前置通知@Before("pointcut()")public void beforeAdvice(){System.out.println("执行力前置通知");}
//    后置通知@After("pointcut()")public void AfterAdvice(){System.out.println("执行了后置通知");}

解释说明:我们不在切点中实现具体方法,是因为我们实现的方法有很多种,所以通过通知进行实现,它们具有1对多的关系。

在UserController类中创建方法检验AOP执行过程:

package com.example.demo_aop.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author zq* @date 2023-07-19 20:25*/@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/hi")public String sayHi(String name){System.out.println("执行了sayHi方法");return "Hi" + name;}@RequestMapping("/hello")public String sayHello(String name){System.out.println("执行了sayHello方法");return "Hello" + name;}}

如图当我们启动程序,访问http://localhost:8080/user/hi时,控制台输出结果符合AOP执行过程
在这里插入图片描述

同理我们可以在切面类中也实现环绕通知,指的注意的是我们在环绕通知中必须通过 object = joinPoint.proceed(); 才能执行目标方法,不然只是执行环绕通知 ;

//    环绕通知@Around("poincut()")
//    它必须有返回值返回给框架public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {Object object = null;System.out.println("进入环绕通知");
//        执行目标方法object = joinPoint.proceed();System.out.println("退出环绕通知");return object;}

执行结果如下:
在这里插入图片描述

5. Spring AOP实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截。Spring AOP ⽀持 JDK Proxy 和 CGLIB 方式实现动态代理。默认情况下,实现了接⼝的类,使⽤ AOP 会基于 JDK 生成代理类,没有实现接口的类,会基于 CGLIB 生成代理类。

也就是说我们本来要访问某个对象,但是我们Spring AOP构造了一个对应的代理类,我们访问时会通过代理类来访问我们的目标对象,不能直接访问

如图所示:对于我们以上代码来说我们本来是访问UserController类,但是我们不能直接访问了,而是通过访问代理类访问。
在这里插入图片描述

两种代理方式的区别:

  1. JDK 实现,要求被代理类必须实现接⼝,之后是通过 InvocationHandler 及 Proxy,在运行时动态的在内存中⽣成了代理类对象,该代理对象是通过实现同样接⼝来实现,只是该代理类是在运行期时,动态的织⼊统⼀的业务逻辑字节码来完成。
  2. CGLIB 实现,被代理类可以不实现接⼝,是通过继承被代理类,在运⾏时动态的生成代理类对象

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

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

相关文章

STM32 Proteus仿真全自动洗衣机洗涤脱水-0074

STM32 Proteus仿真全自动洗衣机洗涤脱水-0074 Proteus仿真小实验&#xff1a; STM32 Proteus仿真全自动洗衣机洗涤脱水-0074 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机LCD1602显示器 L298N驱动电机正反转蜂鸣器LED指示灯多个按键(标准洗&#xff0c;快速洗&a…

STM32学习笔记(十二)丨RTC实时时钟

本篇文章包含的内容 一、计算机底层计时系统——时间戳1.1 时间戳简介1.2 GMT/UTC1.3 C语言和time.h库 二、STM32的BKP和RTC时钟2.1 BKP&#xff08;Backup Registers&#xff09;备份寄存器2.2 RTC&#xff08;Real Time Clock&#xff09;实时时钟2.2.1 RTC简介2.2.2 RTC的内…

javascript 导出表格的excel

一个php网站的表格,需要增加导出excel的功能, 因对web开发不甚了解,开始想着用php导出, 搜索一番发现比较复杂,而且我的表格里已经有数据了, 如果导出又要去库中获取一次,不是负担加倍, 可否把现有表格数据,直接导出来? 答案是肯定的,用js在前端导出 开源js组件…

opencv-07-感兴趣区域(ROI)

在图像处理过程中&#xff0c;我们可能会对图像的某一个特定区域感兴趣&#xff0c;该区域被称为感兴趣区 域&#xff08;Region of Interest&#xff0c;ROI&#xff09;。在设定感兴趣区域 ROI 后&#xff0c;就可以对该区域进行整体操作。 以下是一些 OpenCV ROI应用场景 …

centos环境搭建nsq单点

简言 下载 启动nsq(单节点) 1. 启动nsqd 2. 启动nsqlookupd 3. 启动nsqadmin 查看状态 简言 1. nsq是go语言实现的分布式消息处理平台&#xff0c;类似我们常用的kafka&#xff0c;rocket mq等&#xff0c;目的是用来大规模地处理每天数以十亿计级别的消息。它具有分布式和…

如何用Jmeter做性能测试

目录 性能测试的概念 性能测试类型 性能测试应用场景&#xff08;领域&#xff09; 性能测试常用的指标 性能测试流程 需求分析 搭建测试环境 测试场景设计 测试用例设计和脚本开发 测试数据准备 性能测试执行和管理 性能测试结果分析与调优 测试报告和跟踪 性能测…

AtcoderABC244场

A - Last LetterA - Last Letter 题目大意 给定一个长度为N的字符串S&#xff0c;由小写英文字母组成&#xff0c;打印出S的最后一个字符。 思路分析 题目要求打印出字符串S的最后一个字符&#xff0c;可以直接通过访问S的最后一个元素来获取该字符。可以使用字符串的back()…

用Arthas快速定位线上JVM问题!

Arthas分析FullGC问题定位 对于FullGC那一定不会陌生,一般来说会采用横切FullGC前置拦截(-XX:+HeapDumpBeforeFullGC)和后置拦截(-XX:+HeapDumpAfterFullGC),导出FullGC发生前后的heap dump文件,以便于我们进行FullGC原因的分析和定位。 推测分析问题之FullGC的频率过高…

unity背景缓动动效

这算是一个很常见的小功能&#xff0c;比如我们在玩横版游戏的时候&#xff0c;背景动画会以一定的频率运动&#xff0c;其实现方式也有很多种。 比如&#xff0c;使用UGUI的imageanimtion动画的方式&#xff0c;自己k桢实现。 还可以使用材质球本身的功能来实现&#xff0c;关…

WPF 自定义控件完成库容表盘显示效果

先看一下显示效果&#xff1a; 需要注意的地方有以下几点&#xff1a; 表盘的刻度分部&#xff0c;长刻度和短刻度显示。在数值80W时&#xff0c;需要更改刻度盘的颜色渐变。在数值80W时&#xff0c;更改库容总数背景的显示&#xff0c;也是颜色渐变。刻度盘控件属性定义&…

HarmonyOS课程体验官招募(第四期),寻找乐于分享,精益求精的伙伴

华为开发者联盟HarmonyOS课程体验官&#xff08;第四期&#xff09;活动&#xff0c;开始招募啦&#xff01; 如果你精益求精、乐于分享&#xff1b;如果你愿意为学堂课程优化改进出谋划策&#xff0c;那就快来加入我们吧&#xff01;学堂期待与你共同成长、一起进步&#xff0…

11、动手学深度学习——语言模型和数据集:代码详解

我们了解了如何将文本数据映射为词元&#xff0c;以及将这些词元可以视为一系列离散的观测&#xff0c;例如单词或字符。 假设长度为 T T T的文本序列中的词元依次为 x 1 , x 2 , … , x T x_1, x_2, \ldots, x_T x1​,x2​,…,xT​。于是&#xff0c; x t x_t xt​&#xff08…

GPT与人类:人工智能是否能够真正复制人类语言?

人类语言是一种复杂的系统&#xff0c;它不仅包含着无数单词和语法规则&#xff0c;更重要的是具有丰富的含义和上下文。这些语言特征涉及到常识、文化、情感和经验等方面&#xff0c;是人类在长期进化和文明发展中所积累起来的丰富知识和经验的体现。然而&#xff0c;人工智能…

SpringCloud学习路线(7)—— 统一网关Gateway

一、引言 &#xff08;一&#xff09;需求&#xff1a; 服务器中的微服务只允许内部人员调用或是内网人员进行调用&#xff0c;拒绝外网人员访问。 &#xff08;二&#xff09;如何实现需求&#xff1f; 网关 &#xff08;三&#xff09;网关的功能 身份认证和权限校验服务…

java线上故障排查套路总结

线上故障主要会包括cpu、磁盘、内存以及网络问题&#xff0c;而大多数故障可能会包含不止一个层面的问题&#xff0c;所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题的&#xff0c;基本上出问题就是df、free、top 三连&#x…

Principle Component Analysis

简述PCA的计算过程 输入&#xff1a;数据集X{x1&#xff0c;x2&#xff0c;...&#xff0c;xn}&#xff0c;需降到k维 ① 去中心化&#xff08;去均值&#xff0c;即每个特征减去各自的均值&#xff09; ② 计算协方差矩阵1/nX*X^T&#xff08;1/n不影响特征向量&#xff09…

day39-Oracle分区表

0目录 Oracle分区表 1.2.3 1. Oracle分区表 1.1 作用&#xff1a; Oracle数据库的分区把表中的数据行按照分区划成几个区域&#xff0c;提高大数据量下表的性能 1.2 应用场景&#xff1a;常应用于数据量大的表 1.3 分类&#xff1a;Oracle中有范围分区&#xff08;最常见…

vue使用docxtemplater导出word实现使用textarea输入的内容换行

注:本文只做导出word并且换行操作&#xff0c;不做vue引入docxtemplater步骤 先看一下实现效果 这是文本域输入的 这是导出来的结果 可以看出来导出来的结果也是换行的呢 接下来我们手摸手操作一下流程 首先咱们捋一捋思路 知道文本域的换行的换行标识符&#xff0c;我们发…

[深度学习入门]什么是神经网络?[神经网络的架构、工作、激活函数]

目录 一、前言二、神经网络的架构——以手写数字识别三、神经网络的工作1、单输入单输出感知器函数2、二维输入参数3、三维输入参数 四、激活函数1、激活函数2、ReLU激活函数3、非线性激活函数&#xff08;1&#xff09;二输入二输出的神经网络的架构&#xff08;2&#xff09;…

基于预测控制模型的自适应巡航控制仿真与机器人实现(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 自适应巡航控制技术为目前由于汽车保有量不断增长而带来的行车安全、驾驶舒适性及交通拥堵等问题提供了一条有效的解决途径&am…