AOP 介绍

AOP,也就是 Aspect-oriented Programming,译为面向切面编程

简单点说,就是把一些业务逻辑中的相同代码抽取到一个独立的模块中,让业务逻辑更加清爽。


举个例子,假如我们现在需要在业务代码开始前进行参数校验,在结束后打印日志,该怎么办呢?

我们可以把日志记录数据校验这两个功能抽取出来,形成一个切面,然后在业务代码中引入这个切面,这样就可以实现业务逻辑和通用逻辑的分离。


业务代码不再关心这些通用逻辑,只需要关心自己的业务实现,这样就实现了业务逻辑和通用逻辑的分离。


AOP 的核心概念

  • 切面(Aspect)
    表示增强的功能. 交叉业务逻辑。常见的切面: 日志 事务 统计信息 参数检查

  • 连接点(Join Point)
    在程序执行过程中的某个特定点,例如方法调用、异常抛出等

  • 通知(Advice)
    通知就是切面在某个连接点要执行的操作

  • 切点(Pointcut)
    一个切点是一个表达式,它用来匹配哪些连接点需要被切面所增强。切点可以通过注解、正则表达式、逻辑运算等方式来定义。比如 execution(* com.xyz.service..*(..))匹配

  • 织入(Weaving)
    将切面应用到目标对象中的过程,可以在编译时、加载时或运行时进行。


AOP 的五种通知类型

  • 前置通知(Before)
  • 后置通知(After Returning)
  • 异常通知(After Throwing)
  • 最终通知(After / Finally)
  • 环绕通知(Around)
    前四种通知都是在目标方法的前后执行,而环绕通知可以控制目标方法的执行过程

AOP 的技术实现

1. 静态代理

通过 AOP 框架提供的命令进行编译,从而在编译阶段生成 AOP 代理类。这种方式也被称为编译时增强。静态代理包括编译时编织和类加载时编织两种方式。

2. 动态代理

‍ 动态代理参考地址
在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。动态代理主要有两种实现方式:

  • JDK 动态代理:JDK 动态代理要求被代理的类必须实现一个接口,它通过反射来接收被代理的类,并使用 InvocationHandler 接口和 Proxy 类实现代理。
  • CGLIB 动态代理:CGLIB 则是一个代码生成的类库,它可以在运行时动态地生成某个类的子类,通过继承的方式实现代理。如果目标类没有实现接口,Spring AOP 会选择使用 CGLIB 来动态代理目标类。

‍ 参考地址