当前位置: 首页 > 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.lryc.cn/news/586229.html

相关文章:

  • Python 实战:构建 Git 自动化助手
  • RabbitMQ面试精讲 Day 1:RabbitMQ核心概念与架构设计
  • 网络安全初级第一次作业
  • 医疗AI前端开发中的常见问题分析和解决方法
  • Filament引擎(三) ——引擎渲染流程
  • 【GESP】C++ 2025年6月一级考试-客观题真题解析
  • Apache Iceberg数据湖高级特性及性能调优
  • PyTorch神经网络实战:从零构建图像分类模型
  • 【文献阅读】DEPTH PRO: SHARP MONOCULAR METRIC DEPTH IN LESS THAN A SECOND
  • Rust Web 全栈开发(五):使用 sqlx 连接 MySQL 数据库
  • Spring 框架中的设计模式:从实现到思想的深度解析
  • 单链表的题目,咕咕咕
  • Rust Web 全栈开发(六):在 Web 项目中使用 MySQL 数据库
  • [Python] Flask 多线程绘图时报错“main thread is not in main loop”的解决方案
  • 【字符最长连续数量】2022-8-9
  • wedo稻草人-----第32节(免费分享图纸)
  • windows 改用 nvm
  • hiredis: 一个轻量级、高性能的 C 语言 Redis 客户端库
  • SpringAI实现聊天记录保存到MySQL
  • 浅谈 Python 中的 yield——yield的返回值与send()的关系
  • Golang 面向对象(封装、继承、多态)
  • 特辑:Ubuntu,前世今生
  • Go内存分配
  • python excel处理
  • 【世纪龙科技】新能源汽车结构原理体感教学软件-比亚迪E5
  • Windows 用户账户控制(UAC)绕过漏洞
  • 单细胞分析教程 | (二)标准化、特征选择、降为、聚类及可视化
  • 力扣-24.两两交换链表中的节点
  • 7. 负载均衡:流量调度引擎
  • STM32--USART串口通信的应用(第一节串口通信的概念)