Spring AOP

233 阅读5分钟

AOP 介绍

  • AOP,Aspect-Oriented Programming,面向切面编程。
  • AOP 是一种编程范式,它通过将横切关注点从业务逻辑中分离出来,以模块化的方式实现了横切关注点的复用。
  • AOP 的核心思想是将横切关注点抽象成切面(Aspect),然后通过编织(Weaving)的方式将切面与业务逻辑进行组合,从而实现横切关注点的复用。
  • 切面是一个横跨多个对象的关注点,它可以包含一些通用的逻辑,例如日志记录、异常处理等,通常这些逻辑与具体的业务功能不挂钩。

image.png

  • 在纵向,不同的核心业务模块实现不同的业务功能。
  • 在横向,不同的核心业务模块中有一些与具体业务逻辑无关,但有反复出现的功能,例如日志、监控、事务等。把这些功能抽象成单独模块,一方面可以提升代码复用度,一方面可以让程序员专注于编写核心业务。

使用 AOP 的好处:

  • 代码重用:AOP 可以将通用的功能逻辑抽象成切面,然后将切面与业务逻辑进行组合,从而实现了横切关注点的复用。这样,我们可以将通用的功能逻辑抽象成切面,然后在多个模块中进行复用,从而提高了代码的可重用性。
  • 松耦合:AOP 不侵入业务代码,将横切关注点从业务逻辑中分离出来,提升了代码的可维护性、可扩展性、可读性。

image.png

  • 上图是非 AOP 方式实现统计方法执行耗时的代码
    • 相同的代码要在两个方法中写,没有服用。
    • 非业务代码侵入了核心业务方法,耦合度高。

Spring AOP 实现原理概述

  • AOP 的本质是对目标类方法的增强。目标类的方法只实现业务逻辑,AOP 来完成其他增强逻辑。
  • Spring AOP 使用动态代理来实现,即 Spring 在运行时创建代理对象,代理对象会将方法调用转发给目标对象,并提供方法增强。
  • Spring AOP 的动态代理有两种方式:
    • 基于接口的代理,使用 JDK 动态代理实现,要求目标对象实现接口。
    • 基于类的代理,使用 CGLIB 动态代理实现。

image.png

image.png

AOP 核心术语

  • 切面(Aspect):切面是横切关注点的抽象,它包含了切点和通知。切面定义了在哪些地方(切点)以及何时执行哪些增强操作(通知)。
  • 切点(Pointcut):切点是指在哪些地方应该执行切面的增强操作。
  • 通知(Advice):通知是切面的具体实现,又叫增强,它定义了增强操作的具体行为,是我们抽取出来的共性功能。通知分为:前置通知、后置通知、环绕通知、异常通知、最终通知。
  • 连接点(Joinpoint):连接点是在应用执行过程中能够插入切面的一个点,例如方法调用、方法执行、异常处理等。连接点是切点的基础,切点定义了在哪些连接点上应该执行切面的增强操作。
  • 织入(Weaving):织入是将切面应用到目标对象上的过程。
  • 目标对象(Target):被织入增强的对象。
  • 代理对象(Proxy):一个目标对象被织入增强后产生的新对象。

image.png

  • 切面 1 对方法 1、方法 2 进行增强
  • 切面 2 对方法 2、方法 3 进行增强

Spring AOP 实现

第一步:引入依赖

image.png

第二步:创建 Spring 配置类

image.png

第三步:创建 目标类

image.png

第四步:创建切面(定义切点 + 通知)

image.png

第五步:执行测试方法

image.png

通知 Advice 的类型

  • 前置通知(Before Advice):在目标方法执行前执行的通知。
  • 后置通知(After Advice):在目标方法执行后执行的通知。
  • 返回通知(After Returning Advice):在目标方法执行后返回结果时执行的通知。
  • 异常通知(After Throwing Advice):在目标方法抛出异常时执行的通知。
  • 环绕通知(Around Advice):在目标方法执行前后都执行的通知。

目标方法正常返回

image.png

目标方法执行过程中抛异常

image.png

  • 目标方法抛异常,异常通知才会执行
  • 如果目标方法抛异常,返回通知、后环绕通知不会执行,但后置通知会执行

返回通知和后置通知的区别:

  • 返回通知是在目标方法执行后返回结果时执行的通知,只有目标方法正常返回时才会执行,抛异常则不会执行。返回通知可以访问目标方法的返回值,并可以修改返回值
  • 后置通知是在目标方法执行后执行的通知,无论目标方法是否抛出异常,后置通知都会执行。后置通知无法访问目标方法的返回值或抛出的异常。
  • 因此,后置通知和返回通知的区别在于它们的执行时机和作用。后置通知无法访问目标方法的返回值或抛出的异常,而返回通知可以访问目标方法的返回值,并可以修改返回值。在实际应用中,我们需要根据具体的需求选择使用后置通知还是返回通知。

通用切点

可以定义通用切点,减少重复开发。

image.png

image.png

使用注解定义切点

可以使用注解来定义切点,切入更灵活。

image.png

image.png

image.png

Spring AOP 实战

目标:

  • 执行方法前,打印类名、方法名、执行参数
  • 统计方法执行时间

image.png

image.png

image.png

Spring 接入日志

image.png

image.png

image.png

image.png

image.png

image.png