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

【Spring AOP】什么是AOP?切点、连接点、通知和切面

AOP 概述

AOPSpring 框架的第二大核心(第一大是 IoC

什么是 AOP

  • Aspect Oriented Programming(面向切面编程)

什么是面向切面编程呢?切面就是指某一类特定问题,所以 AOP 也可以理解为面向特定方法编程

什么是面向特定方法编程呢?比如前面说到的“登录校验”,就是一类特定问题

  • 登录校验拦截器,就是对“登录校验”这类问题的统一处理
  • 所以,拦截器也是 AOP 的一种应用

AOP 是一种思想,拦截器是 AOP 思想的一种实现,Spring 框架实现了这种思想,提供了拦截器技术的相关接口

简单来说:AOP 是一种思想,是对某一类事情的集中处理

什么是 Spring AOP

AOP 是一种思想,它的实现方法有很多,由 Spring AOP,也有 AspectJCGLIB

  • Spring AOP 只是其中的一种实现方式

拦截器作用的维度是 URL(一次请求和响应),@ControllerAdvice 应用场景主要是全局异常处理(配合自定义异常效果更佳),数据绑定,数据预处理。AOP 作用的维度更加细致(可以根据包、类、方法名、参数等进行拦截),能够实现更加复杂的业务逻辑


举个例子:
我们现在有个项目,项目中开发了很多的业务功能image.png
现在有一些业务的执行效率比较低,耗时较长,我们需要对接口进行优化

  • 第一步就需要定位出执行耗时比较长的业务方,再针对该业务方法来进行优化

如何定位呢?我们就需要统计当前项目中每一个业务方法的执行耗时

  • 可以在业务方法运行前和运行后,记录下方法的开始时间和结束时间,两者的差就是这个方法的耗时image.png

这种方法是可以解决问题的,但一个项目中会包含很多的业务模块,每个业务模块又有很多接口,一个接口又包含了很多方法,如果我们要在每个业务方法中都记录方法的耗时,对于程序员而言,会增加很多的工作量

AOP 就可以做到在不改动这些原始方法的基础上,针对特定的方法进行功能的增氧

  • AOP 的作用:在程序运行期间在不断修改源代码的基础上对已有方法进行增强(无侵入性:解耦

Spring AOP 快速入门

引入依赖

pom.xml 中添加配制

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

编写 AOP 程序

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  
@Component  
public 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;  }  
}
  • 运行程序,观察日志:image.png

对程序进行简单讲解:

  1. @Aspect:标识这是一个切面类
  2. @Around:环绕通知,在目标方法的前后都会被执行。后面的表达式表是对哪些方法进行增强
  3. PeoceedingJoinPoint.proceed() 让原始方法执行

整个代码分为三个部分 image.png
我们通过 AOP 入门程序完成了业务接口执行耗时的统计。通过上面的代码,我们可以感受到 AOP 面向切面编程的一些优势:

  • 代码无侵入:不修改原始的业务方法,就可以对原始的业务方法进行了功能的增强或者是功能的改变
  • 减少了重复代码
  • 提高了开发效率
  • 维护方便

Spring AOP 详解

下面我们来详细学习 AOP,主要是以下几部分

  • Spring AOP 中涉及的核心概念
  • Spring AOP 通知类型
  • 多个 AOP 程序的执行顺序

Spring AOP 核心概念

1. 切点(Pointcut)

切点(Pointcut),也称之为“切入点

Pointcut 的作用就是提供一组规则(使用 AspectJ pointcut expression language 来描述),告诉程序对哪些方法来进行功能增强image.png

  • 上面的表达式 execution(* com.example.demo.controller.*.*(..)) 就是切点表达式

2. 连接点(Join Point)

满足切点表达式规则的方法,就是连接点,也就是可以被 AOP 控制的方法

以入门程序举例,所有 com.example.demo.controller 路径下的方法,都是连接点

package com.example.demo.controller;@RequestMapping("/book")
@RestController
public class BookController {@RequestMapping("/addBook")public Result addBook(BookInfo bookInfo) {//...代码省略}@RequestMapping("/queryBookById")public BookInfo queryBookById(Integer bookId) {//...代码省略}@RequestMapping("/updateBook")public Result updateBook(BookInfo bookInfo) {//...代码省略}
}
  • 上述 BookController 中的方法都是连接点

切点和连接点的关系

  • 连接点是满足切点表达式的元素
  • 切点可以看做是保存了众多连接点的集合
    比如:
  • 切点表达式:全校老师
  • 连接点就是:张老师、李老师、王老师等各个老师

3. 通知(Advice)

通知就是具体要做的工作,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)

比如上述程序中记录业务方法的耗时时间,就是通知image.png

  • AOP 面向切面编程当中,我们把这部分重复的代码抽取出来单独定义,这部分代码就是通知的内容

4. 切面(Aspect)

切面(Aspect)=切点(Pointcut)+通知(Advice

通过切面就能够描述当前 AOP 程序需要针对哪些方法,在什么时候执行什么样的操作

  • 切面既包含了通知逻辑的定义,也包括了连接点的定义
    image.png
  • 切面所在的类,我们一般称为切面类(被 @Aspect 注解标识的类)
http://www.dtcms.com/a/275472.html

相关文章:

  • SELECT ... INTO OUTFILE和LOAD DATA INFILE
  • Power Switch:用途、原理、工作方式及实现方案
  • CSS选择器进行定位
  • OneCode 3.0 DDD领域模型开放接口:基于DSMFactory的架构解析与实践指南
  • OBOO鸥柏丨满天星(MTSTAR)多媒体信息发布系统技术解析
  • Vscode中使用C++代码进行debug
  • Javaweb- 11 MVC架构模式
  • [BJDCTF2020]ZJCTF,不过如此
  • HarmonyOS从入门到精通:动画设计与实现之六 - 动画曲线与运动节奏控制
  • Leetcode百题斩-二分搜索
  • 【C语言】回调函数、转移表、qsort 使用与基于qsort改造冒泡排序
  • linux_线程概念
  • 死锁的概念 ⚠️
  • 告别频繁登录!Nuxt3 + TypeScript + Vue3实战:双Token无感刷新方案全解析
  • TinyBERT:知识蒸馏驱动的BERT压缩革命 | 模型小7倍、推理快9倍的轻量化引擎
  • python-for循环
  • 【Elasticsearch】昂贵算法与廉价算法
  • UI前端大数据可视化实战策略分享:如何设计符合用户认知的数据可视化流程?
  • 让 VSCode 调试器像 PyCharm 一样显示 Tensor Shape、变量形状、变量长度、维度信息
  • 「日拱一码」025 机器学习——评价指标
  • Android音视频探索之旅 | C++层使用OpenGL ES实现音频渲染
  • 单片机学习笔记.根据芯片数据手册写驱动程序(这里使用的是普中开发版,以DS1302为例)
  • 创建Spring Boot项目
  • 解决‘vue‘ 不是内部或外部命令,也不是可运行的程序
  • 前端开发的「设计鸿沟」:为什么我学了CSS却做不出好看的网页?
  • 用YOLOv5系列教程(1)-用YOLOv5轻松实现设备状态智能监控!工业级教程来了
  • 【工具】什么软件识别重复数字?
  • C++结构体的定义与使用
  • 机器学习(ML)、深度学习(DL)、强化学习(RL)关系和区别
  • Redis 基本操作笔记