AOP的应用场景
1、日志记录
2、权限验证
3、效率检查(个人在代码上,喜欢用注解 + 切面,实现校验,redis分布式锁等功能)
4、事务管理(spring 的事务就是用AOP实现的)
spring AOP 和 AspectJ的关系
两者都是为了实现AOP这个目的,而出现的技术,spring aop 参考 AspectJ编程风格,在基于Spring AOP编程的过程中,基于AspectJ框架标准,spring中定义了五种类型的通知,它们分别是:
- 前置通知 (@Before)
- 返回通知 (@AfterReturning)
- 异常通知 (@AfterThrowing)
- 后置通知 (@After)
- 环绕通知 (@Around) :(优先级最高)
简述一下Spring AOP的设计原理
代理的创建
创建代理工厂:拦截器数组,目标对象接口数组,目标对象。
创建代理工厂时,默认会在拦截器数组尾部再增加一个默认拦截器 — 用于最终的调用目标方法。
当调用 getProxy 方法的时候,会根据接口数量大余 0 条件返回一个代理对象(JDK or Cglib)。
注意:创建代理对象时,同时会创建一个外层拦截器,这个拦截器就是 Spring 内核的拦截器,用于控制整个 AOP 的流程。
代理的调用
当对代理对象进行调用时,就会触发外层拦截器。
外层拦截器根据代理配置信息,创建内层拦截器链。创建的过程中,会根据表达式判断当前拦截是否匹配这个拦截器。而这个拦截器链设计模式就是职责链模式。
当整个链条执行到最后时,就会触发创建代理时那个尾部的默认拦截器,从而调用目标方法,最后返回。
什么时候Spring Aop会失效
- 要增强的类或方法没被spring管理
- 要被增强的类或方法同时被spring和springMVC扫描,spring mvc的xml中重复扫描了
- 用的注解方式没有开启注解支持
- 在一个类内部调用时,被调用方法的 AOP 声明将不起作用
- 对于基于接口动态代理的 AOP 事务增强来说,由于接口的方法都必然是
public
这就要求实现类的实现方法也必须是public
的(不能是protected、private
等),同时不能使用static
的修饰符。 - 基于CGLib 字节码动态代理的方案是通过扩展被增强类,动态创建其子类的方式进行 AOP 增强植入的,由于使用
final、static、private
修饰符的方法都不能被子类覆盖,这些方法将无法实施 AOP 增强。
文章参考自:
是什么导致了Spring Aop失效了?
AOP失效了...分析
Spring AOP有哪些通知类型,它们的执行顺序是怎样的?