总结一下Spring中AOP的流程,对于具体的源码分析以前写过文档,网上也有很多类似的文章,这里不做重复。
Spring AOP流程大致上可以分为三个阶段:标签解析和AutoProxyCreator的注册、AOP代理的创建、代理的使用。
在Spring的扩展点中,最早期的扩展点是NamespaceHandler,这个阶段是在解析成BeanDefinition的阶段。Spring在这里完成自定义标签的解析工作,比如aop、tx等等。AOP功能在这里注册了自己的NamespaceHandler以及BeanDefinitionParser,用来将AOP标签转换成BeanDefinition交给IOC容器管理。
同时在这里也会注册一个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实现使用的是动态代理和拦截器连。