0%

Spring中AOP流程的总结

总结一下Spring中AOP的流程,对于具体的源码分析以前写过文档,网上也有很多类似的文章,这里不做重复。

Spring AOP流程大致上可以分为三个阶段:标签解析和AutoProxyCreator的注册、AOP代理的创建、代理的使用。

标签解析和AutoProxyCreator的注册

在Spring的扩展点中,最早期的扩展点是NamespaceHandler,这个阶段是在解析成BeanDefinition的阶段。Spring在这里完成自定义标签的解析工作,比如aop、tx等等。AOP功能在这里注册了自己的NamespaceHandler以及BeanDefinitionParser,用来将AOP标签转换成BeanDefinition交给IOC容器管理。

关于AutoProxyCreator的理解

同时在这里也会注册一个AutoProxyCreator,这个组件是用来在后面Bean的初始化过程中生成代理的。这个AutoProxtCreator实现了一个接口是:SmartInstantiationAwareBeanPostProcessor,看起来很眼熟,SmartInstantiationAwareBeanPostProcessor这个接口的父接口是:InstantiationAwareBeanPostProcessor,而InstantiationAwareBeanPostProcessor的父接口是BeanPostProcessor,到这里我们可能就大概明白了。

我们知道实现了BeanPostProcessor接口的类会在Bean初始化过程中的填充属性之后这一步被调用,调用的方法是postProcessBeforeInitialization和postProcessAfterInitialization。但是Spring干嘛还要衍生出那么多子接口呢?通过接口的名字我们可以看到不同,那些接口名字都含有一个关键词:Instantiation实例化,并不是初始化Initialization,也就是说这些接口中的方法调用是要在Bean实例化的时候进行处理。在Bean的生命周期中,我们知道Bean的实例化是Bean初始化步骤中最早的一步,所以对于Instantiation等方法的处理会比Initialization要早。

试想一下,我们自己写这些逻辑的时候,会在什么时候去创建AOP代理?第一个时间点:在Bean实例化之前,我就通过创建代理的逻辑直接返回一个代理好的实例,就不用继续走Bean初始化的后面的步骤了;第二个时间点:在Bean初始化之后,也就是走完了所有的Bean初始化过程后生成了一个完整的Bean,我再进行代理的创建。Spring就是这么处理的,要么我就不用Spring创建Bean,我直接返回一个代理,要么我就等Spring创建完成一个Bean再返回一个代理。Spring还有会另外一个触发点创建代理:getEarlyBeanReference,用来在解决循环依赖时提前曝光的Bean的代理生成,暂时不做说明。

AOP代理创建

明确了代理创建的时间点,就可以继续看AOP代理的创建过程了。

  1. 筛选出所有适合当前Bean的通知器,也就是所有的Advisor、Advise、Interceptor。
  2. 选择使用JDK还是CGLIB来进行创建代理。
  3. 使用具体的代理实现来创建代理。

过程简单,但是实际的细节和实现还很复杂。

代理的使用

  1. 获取当前调用方法的拦截器链,包含了所有将要执行的advice。
  2. 如果没有任何拦截器,直接执行目标方法。
  3. 如果有拦截器存在,则将拦截器和目标方法封装成一个MethodInvocation,递归调用proceed方法进行调用。
  4. 上面的处理中还有对目标对象的自我方法调用实施增强的处理,比如平时遇到的问题:在同一个类中一个方法调用另外一个带事务注解的方法,事务不会生效;在同一个类中一个方法调用另外一个带缓存注解的方法,缓存不会生效。

以上就是大概的流程,总结一下就是:AOP实现使用的是动态代理和拦截器连。

坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub