Spring AOP

本文详细介绍了SpringAOP的概念,包括面向切面编程的背景、为何使用AOP以及如何学习。重点讲解了AOP的四个核心组件:切面、连接点、切点和通知,并提供了实际的SpringAOP实现步骤。此外,还阐述了SpringAOP的动态代理实现方式(JDK和CGLIB)以及织入过程。最后,通过一个俱乐部的比喻帮助理解AOP的工作原理。
摘要由CSDN通过智能技术生成

1.什么是 Spring AOP?

AOP(Aspect Oriented Programming):面向切面编程,它是一种思想,它是对某一类事情的集中处理
AOP的诞生不是为了替代OOP,AOP相对于OOP来说,是一个补充的关系,不是一个替代的关系。
AOP 是一种思想, Spring AOP 是一个框架,提供了一种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。

2.为什么要用AOP?

  • 统一的用户登录判断

AOP 还可以实现:

  • 统一日志记录
  • 统一方法执行时间统计
  • 统一的返回格式设置
  • 统一的异常处理
  • 事务的开启和提交等

使用AOP 可以扩充多个对象的某个能力,所以 AOP 可以说是 OOP(Object Oriented Programming,面向对象编程)的补充和完善。

3.Spring AOP 应该怎么学习呢?

Spring AOP 学习主要分为以下 3 个部分:

  1. 学习 AOP 是如何组成的?也就是学习 AOP 组成的相关概念。
  2. 学习 Spring AOP 使用。
  3. 学习 Spring AOP 实现原理。

3.1 AOP 组成

3.1.1 切面(Aspect)

切面(Aspect)由切点(Pointcut)和通知(Advice)组成,它既包含了横切逻辑的定义,也包括了连接点的定义。

切面是包含了:通知、切点和切面的类,相当于 AOP 实现的某个功能的集合。

定义AOP的业务类型(要干嘛:要验证登录?要记录日志?要统计方法执行时间?)

3.1.2 连接点(Join Point)

应用执行过程中能够插入切面的一个点,这个点可以是方法调用时,抛出异常时,甚 修改字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

连接点相当于需要被增强的某个 AOP 功能的所有方法。

AOP中的所有方法

3.1.3 切点(Pointcut)

Pointcut 是匹配 Join Point 的谓词。

Pointcut 的作用就是提供一组规则(使 AspectJ pointcut expression language 来描述)来匹配 Join Point,给满足规则的 Join Point 添加 Advice。

切点相当于保存了众多连接点的一个集合(如果把切点看成一个表, 连接点就是表中一条一条的数据)。

提供一组规则,用来匹配连接点

3.1.4 通知(Advice)

切面也是有目标的 ——它必须完成的工作。在 AOP 术语中,切面的工作被称之为通知。

通知:定义了切面是什么,何时使用,其描述了切面要完成的工作,还解决何时执行这个工作的问题。

提供AOP方法实现

5个通知类型:

  • 前置通知:使用@Before:通知方法会在目标方法调用之前执行。
  • 后置通知:使用@After:通知方法会在目标方法返回或者抛出异常后调用。
  • 异常返回之后通知:使用@AfterThrowing:通知方法会在目标方法抛出异常后调用。
  • return之后通知:使用 @AfterReturning:通知方法会在目标方法返回后调用。
  • 环绕通知:使用@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为。

切点相当于要增强的方法。

AOP 整个组成部分的概念如下图所示,以多个页面都要访问用户登录权限为例:

在这里插入图片描述
可以这样通俗理解:
切面相当于一个俱乐部,连接点为想进去俱乐部的用户,而切点是一个VIP条件,它规定了VIP用户可以进入俱乐部,而非VIP的用户不可以进入这个俱乐部;通知就是会员在俱乐部里面可以玩什么(例如三国杀、剧本杀等,总共5类)

3.2 Spring AOP 实现

接下来我们使用Spring AOP 来实现一下 AOP 的功能,完成的目标是拦截所有UserController 的方法,每次调 UserController 中任意一个方法时,都执行相应的通知事件。
Spring AOP 的实现步骤如下:

  1. 添加 Spring AOP 框架支持。
  2. 定义切面和切点。
  3. 定义通知。

3.2.1 添加 AOP 框架支持

创建Spring Boot项目;

Maven中央仓库
在这里插入图片描述
选择和自己创建Spring Boot版本相同的版本号:
我的为Spring Boot 2.6.10
在 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>
    <version>2.6.10</version>
</dependency>

记得添加完成后点击导入!!

3.2.2 定义切面和切点

切点指的是具体要处理的某一类问题,比如用户登录权限验证就是一个具体的问题,记录所有方法的执行日志就是一个具体的问题,切点定义的是某一类问题。

a) 定义切面:
在这里插入图片描述
b) 定义切点
在这里插入图片描述
切点表达式说明:

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

在这里插入图片描述
表达式示例:
execution(* com.cad.demo.User.* (…)) :匹配 User 类里的所有方法。
execution(* com.cad.demo.User+.* (…)) :匹配该类的子类包括该类的所有方法。
execution(* com.cad.* .* (…)) :匹配 com.cad 包下的所有类的所有方法。
execution(* com.cad…* .* (…)) :匹配 com.cad 包下、子孙包下所有类的所有方法。
execution(* addUser(String, int)) :匹配 addUser 方法,且第一个参数类型是 String,第二个参数类型是 int。

3.2.3定义通知

5个通知类型:

  • 前置通知:使用@Before:通知方法会在目标方法调用之前执行。
  • 后置通知:使用@After:通知方法会在目标方法返回或者抛出异常后调用。
  • 异常返回之后通知:使用@AfterThrowing:通知方法会在目标方法抛出异常后调用。
  • return之后通知:使用 @AfterReturning:通知方法会在目标方法返回后调用。
  • 环绕通知:使用@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为。
    前置通知:
    在这里插入图片描述
    后置通知:
    在这里插入图片描述
    异常返回之后通知:
    在这里插入图片描述
    返回值通知:
    在这里插入图片描述

后置通知@After执行在@AfterReturning之后

环绕通知:
在这里插入图片描述

3.3 Spring AOP 实现原理

Spring AOP 是构建在动态代理基础上,能够代理的最小单位为方法

在这里插入图片描述
Spring AOP代理实现方式:

  1. JDK Porxy(JDK动态代理)
  2. GGLIB(基于字节码的动态代理)

默认情况下,实现了接口的类,使用AOP 会基于 JDK 生成代理类,没有实现接口的类,会基于 CGLIB 生成代理类。

3.3.1织入(Weaving):代理的生成时机

Sping AOP是在程序运行期织入代理对象。

织入是把切面应用到目标对象并创建新的代理对象的过程,切面在指定的连接点被织入到目标对象中。
在目标对象的生命周期里有多个点可以进行织入:

JDK 和 CGLIB 实现的区别

  1. JDK 实现,要求被代理类必须实现接口 ,之后是通过InvocationHandlerProxy,在运行时动态的在内存中生成了代理类对象,该代理对象是通过实现同样的接口实现(类似静态代理接口实现的方式),只是该代理类是在运行期时,动态的织入统一的业务逻辑字节码来完成。
    2.CGLIB 实现,被代理类可以不实现接口,是通过继承被代理类,在运行时动态的生成代理类对象。

总结

AOP 是对某方面能力的统一实现,它是一种实现思想,Spring AOP 是对 AOP 的具体实现,Spring AOP 可通过 AspectJ(注解)的方式来实现 AOP 的功能,Spring AOP 的实现步骤是:

  1. 添加 AOP 框架支持。
  2. 定义切面和切点。
  3. 定义通知。
    Spring AOP 是通过动态代理的方式,在运行期将 AOP 代码织入到程序中的,它的实现方式有两种:JDK Proxy 和 CGLIB。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值