Dawn's Blogs

分享技术 记录成长

0%

SSM学习之Spring (3) AOP

AOP

面向切面编程也是一种设计思想,核心思想就是将横切关注点从核心业务逻辑中分离出来,形成一个个的切面(Aspect)

Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象;对于没有实现接口的对象,Spring AOP 会使用 CGLIB 生成一个被代理对象的子类来作为代理。

SpringAOPProcess

也可以使用 AspectJ,AspectJ 算的上是 Java 生态系统中最完整的 AOP 框架了。

Spring AOP 和 AspectJ AOP 的区别?

  • 实现原理不同:Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。** Spring AOP 基于代理,而 AspectJ 基于字节码操作。

  • Spring AOP 集成了 AspectJ AOP:Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单,

  • AspectJ 更快:如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。

AOP 的应用场景:

  • 日志记录:自定义日志记录注解,利用 AOP,一行代码即可实现日志记录。
  • 性能统计:利用 AOP 在目标方法的执行前后统计方法的执行时间,方便优化和分析。
  • 事务管理:@Transactional 注解基于 AOP 实现的,可以让 Spring 进行事务管理比如回滚异常操作,免去了重复的事务管理逻辑。
  • 权限控制:利用 AOP 在目标方法执行前判断用户是否具备所需要的权限,如果具备,就执行目标方法,否则就不执行。
  • 接口限流:利用 AOP 在目标方法执行前通过具体的限流算法和实现对请求进行限流处理。
  • 缓存管理:利用 AOP 在目标方法执行前后进行缓存的读取和更新。
  • 。。。。。。

核心概念

AOP中的术语:

  • 横切关注点(cross-cutting concerns) :多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等)。
  • 切面(Aspect):对横切关注点进行封装的类,一个切面是一个类。切面可以定义多个通知,用来实现具体的功能。
  • 连接点(JoinPoint):连接点是方法调用或者方法执行时的某个特定时刻(如方法调用、异常抛出等)。
  • 通知(Advice):通知就是切面在某个连接点要执行的操作。通知有五种类型,分别是前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。前四种通知都是在目标方法的前后执行,而环绕通知可以控制目标方法的执行过程。
  • 切点(Pointcut):一个切点是一个表达式,它用来匹配哪些连接点需要被切面所增强。切点可以通过注解、正则表达式、逻辑运算等方式来定义。比如 execution(* com.xyz.service..*(..))匹配 com.xyz.service 包及其子包下的类或接口。
  • 织入(Weaving):织入是将切面和目标对象连接起来的过程,也就是将通知应用到切点匹配的连接点上。

通知类型

Spring AOP 中定义的通知类型:

  • Before(前置通知):目标对象的方法调用之前触发。
  • After (后置通知):目标对象的方法调用之后触发。
  • AfterReturning(返回通知):目标对象的方法调用完成,在返回结果值之后触发。
  • AfterThrowing(异常通知):目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。
  • Around (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法

切面的执行顺序

多个切面的执行顺序如何控制,有两种方法:

  • @Order 注解,值越小优先级越高。
  • 通过实现 Ordered 接口,重新 getOrder 方法实现。