1. 什么是EnableAspectJAutoProxy
@Import({AspectJAutoProxyRegistrar.class}),给容器中导入AspectJAutoProxyRegistrar,然后自定义注册到容器中的bean,并且判断是否要注册internalAutoProxyCreator,而AnnotaionAwareAspectJAutoProxyCreator实际上是实现了BeanPostProcessor(bean的后置处理器),在bean的初始化前后会调用逻辑,并且它也实现了BeanFactoryAware,可以实现setBeanFactory方法
2. AnnotaionAwareAspectJAutoProxyCreator
2.1 实现了BeanPostProcessor
AbstractAutoProxyCreator实现了postProcessBeforeInstantiation()方法以及postProcessAfterInstantiation,并在其子类中沿用
2.2 实现了BeanFactoryAware接口
- AbstractAutoProxyCreator实现了setBeanFactory()方法,
- AbstractAdvisorAutoProxyCreator继承了AbstractAutoProxyCreator,并重写了setBeanFactory方法,并且调用了一个initBeanFactory方法
- AnnotationAwareAspectJAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,并重写了initBeanFactory方法
2.3 initBeanFactory方法
2.3.1. 传入配置类,创建IOC容器
2.3.2. 注册配置类,调用refresh()刷新容器
2.3.3. registerBeanPostProcessor()注册bean的后置处理器
- 先获取ioc容器所有已经定义的BeanPostProcessor
- 给容器中添加其他的BeanPostProcessor
- 优先注册实现了ProrityOrdered接口的BeanPostProcessor
- 然后注册实现了Ordered接口的BeanPostProcessor
- 注册没实现优先级接口的BeanPostProcessor
- 创建BeanPostProcessor对象到容器中
- 创建Bean的实例
- 给bean的属性赋值,populatebean
- 初始化bean initializingBean
- invokeAwareMethods(),处理aware接口的方法回调
- applyBeanPostProcessorBeforeInitialization,调用BeanPostProcessor的初始化前的操作
- invokeInitMethod()执行自定义的初始化方法
- applyBeanPostProcessorBeforeInitialization,调用BeanPostProcessor的初始化后的操作
- 调用setBeanFactory方法
AbstractAutowireCapableBeanFactory#invokeAwareMethods //调用XXXAware接口的回调方法,这里一次判断当前bean是否是XXXAware接口的实例并触发其回调方法 private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware)bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = this.getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware)bean).setBeanFactory(this); } } } - AnnotationAwareAspectJAutoProxyCreator创建成功
- 给BeanPostProcessor注册到BeanFactory里面
2.3.4. 调用AbstractApplicationContext#finishBeanFactoryInitialization方法,完成BeaFactory方法初始化
-
遍历容器中的所有Bean,依次通过getBean方法创建对象 getBean-> doGetBean-getSingleton,众所周知,spring中doXXX()才是实际处理的方法。
-
创建Bean AnnotationAwareAspectJAutoProxyCreator在所有Bean实例创建之前会拦截,并调用AbstractAutoProxyCreator#postProcessBeforeInstantiation的方法
- 先从缓存中获取Bean,如果能够获取得到,说明是之前创建的,直接使用,否则创建,只要创建好的bean都会被缓存起来
- createBean 创建Bean
BeanPostProcessor是在Bean对象创建完成初始化前后调用的,而InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器处理
resolveBeforeInstantiation在这里希望返回一个代理对象,如果能返回代理对象就直接使用,不能就再次调用doCreateBeanbeanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse); if (beanInstance != null) { return beanInstance; } - 后置处理器尝试返回对象
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation //如果实现了InstantiationAwareBeanPostProcessor,则需要进行AOP代理 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } }判断是否是InstantiationAwareBeanPostProcessor的实例,如果是就执行postProcessBeforeInstantiation方法 - doCreateBean 真正的去创建一个实例
2.4 InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法的作用
2.4.1. 每一个Bean创建之前,调用postProcessBeforeInstantiation方法
- 判断当前bean是否在advisedBeans中
- 判断当前bean是否是基础类型的(Advice,Advisor,AopInfrastrucatureBean)
- 判断是否需要跳过
- 获取候选的增强器(即切面方法),判断增强器的类型是否是AspectJPointcutAdvisor
2.4.2. 创建完对象,调用postProcessAfterInstantiation方法
- wrapIfNecessary(Object bean, String beanName, Object cacheKey)
- 获取当前的所有增强器(切面方法)
- 找到能在当前bean使用的通知方法(即哪些方法是需要切入的)
- 给可用的增强器进行排序
- 保存当前Bean到advisedBeans中
- 如果bean需要增强,创建代理对象
- 获取所有增强器
- 保存到proxyFactory
- 创建代理对象,由Spring来决定创建Cglib的动态代理还是JDK的动态代理
- 给容器中返回已经被Cglib代理增强后的对象
- 以后容器中获取到的是代理对象,执行目标方法的时候,代理对象就会执行通知方法
2.4.3. 目标方法执行
容器中保存了组件的代理对象(cglib增强后的对象),这个对象保存了所有的增强器、目标对象信息
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- 进入到CglibProxy#intercept方法,拦截目标方法的执行
- 根据ProxyFactory对象获取目标方法拦截器链
- 遍历所有的增强器,将其转为Interceptor,这其中用到了适配器将增强器转为Interceptor
- 如果没有拦截器链,直接执行目标方法 拦截器链实际上每一个通知方法被包装为拦截器,利用MethodInterceptor机制
- 如果由拦截器链,把需要执行的目标对象的目标方法以及拦截器链等信息创建一个CglibMethodInvocation对象并调用它的proceed方法
- 拦截器链的触发过程:
- 如果没有拦截器,直接执行目标方法,或者拦截器的当前索引等于拦截器数组大小减一,也会执行目标方法
- 链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回然后再执行,责任链模式来保证通知方法的执行顺序
3. 总结
- 利用EnableAspectJAutoProxy开启AOP功能
- EnableAspectJAutoProxy会给容器注册一个AnnotaionAwareAspectJAutoProxyCreator
- 而AnnotaionAwareAspectJAutoProxyCreator是一个BeanPostProcessor(后置处理器)
- 容器的创建过程中:AbstractApplicationContext#refresh方法
- registerBeanPostProcessor()注册后置处理器
- finishBeanFactoryInitialization初始化剩下的单实例Bean
- 创建业务逻辑组件和切面组件
- AnnotaionAwareAspectJAutoProxyCreator 拦截组件的创建过程
- 组件创建完之后判断是否需要增强
- 如果需要增强(切面的通知方法),包装成增强器(advisor)
- 给业务组件创建一个代理对象
- 执行目标方法
- 代理对象执行目标方法
- CglibAopProxy#intercept方法拦截
- 通过包装增强器得到目标方法的拦截器链(MethodInterceptor数组,这个数组安装执行顺序的倒序排序)
- 利用拦截器的链式机制,逐一进入每一个拦截器进行执行
- 正常结果 前置通知 -> 目标方法 -> 后置通知 -> 返回通知
- 异常结果 前置通知 -> 目标方法 -> 后置通知 -> 异常通知