个人学习笔记
启动Aop注解
@EnableAspectJAutoProxy
@Import(AspectJAutoProxyRegistrar.class)给容器中导入组件AspectJAutoProxyRegistrar
利用AspectJAutoProxyRegistrar 自定义给容器注册名叫internalAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator 的Bean
查看AnnotationAwareAspectJAutoProxyCreator 继承关系
AnnotationAwareAspectJAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator
ProxyProcessorSupport->Ordered接口
SmartInstantiationAwareBeanPostProcessor接口->BeanPostProcessor
BeanFactoryAware接口
关注BeanPostProcessor后置处理器和BeanFactoryAware自动装配接口
AbstractAutoProxyCreator.后置处理器逻辑
AbstractAutoProxyCreator.setBeanFactory(BeanFactory)
流程
1、传入配置类,创建IOC容器。new AnnotationConfigApplicationContext(AopConfig.class);
2、注册配置类,调用refresh();刷新容器
3、registerBeanPostProcessors(beanFactory);注册bean的后置处理器,方便拦截bean的创建
1、获取到IOC已经定义了,需要创建对象的所有的BeanPostProcessor
2、给容器中加入其他需要的 PostProcessor -》beanFactory.addBeanPostProcessor()
3、将获取到所有的bean分类存储
4、先注册实现了PriorityOrdered接口的BeanPostProcessor
5、
6、最后注册什么都没有的BeanPostProcessor
7、注册BeanPostProcessor,就是创建BeanPostProcessor对象保存到容器中
注册internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator过程
getBean->doGetBean()->createBean()->doCreateBean()
1、创建bean实例
2、populateBean(beanName, mbd, instanceWrapper);给bean的属性赋值
3、initializeBean(beanName, exposedObject, mbd);初始化bean
1、invokeAwareMethods()处理aware接口的方法回调
2、applyBeanPostProcessorsBeforeInitialization(),应用后置处理器的beanProcessor.postProcessBeforeInitialization();初始化之前调用
3、invokeInitMethods() 执行自定义初始化
4、applyBeanPostProcessorsAfterInitialization() ,应用后置处理器的beanProcessor.postProcessAfterInitialization();;初始化之后调用
创建完成 BeanPostProcessor【AnnotationConfigApplicationContext->InstantiationAwareBeanPostProcessor】
8、把注册好的BeanPostProcessor注册到BeanFactory中
beanFactory.addBeanPostProcessor()
4、finishBeanFactoryInitialization(beanFactory);完成beanFactory初始化工作,创建剩下的单实例bean
AnnotationAwareAspectJAutoProxyCreator会在bean创建之前进行拦截,调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
1、遍历所有的bean,依次创建对象
getBean()->doGetBean()->getSingleton()
2、创建bean
1、先从缓存中获取bean,如果有直接使用,没有就创建,只要创建好的bean都会被缓存起来。
2、createBean,创建bean,AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前尝试返回bean实例。
【BeanPostProcessor是在bean对象创建完成初始化前后调用】
【InstantiationAwareBeanPostProcessor是在创建bean实例之前先尝试用后置处理器返回对象 】
resolveBeforeInstantiation(beanName, mbdToUse);
根据注释希望在这返回一个代理对象,如果不能就继续
1、后置处理器先尝试返回对象
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor
就执行postProcessBeforeInstantiation
1、在每个bean创建之前调用postProcessBeforeInstantiation
只关心CalService和LogAspect
2、判断是否在advisedBeans中,advisedBeans保存了所有的增强bean
3、判断bean是否是基础类,Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否有@Aspect是否是切面;
4、是否需要跳过
获取候选的增强器(切面里面的通知方法),判断每个增强器是否是AspectJPointcutAdvisor类型
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
3、doCreateBean(beanName, mbdToUse, args);真正的创建bean
1、调用postProcessAfterInitialization 创建bean
return wrapIfNecessary(bean, beanName, cacheKey);包装如果需要的话
1、获取当前bean的所有的增强器(通知方法)
1、找到候选的所有的增强器(找到哪些通知方法需要切入当前bean方法)
2、找到能在bean使用的增强器
3、给增强器排序
2、保存当前bean在advisedBeans中
3、如果当前bean需要增强,,创建当前bean的代理对象
2、给容器中返回使用了cglib增强的代理对象
4、目标方法执行
容器中保存了组件的代理对象,这个对象保存了详细信息(比如增强器,目标对象等等)
1、CglibAopProxy.intercept()拦截目标方法的执行
根据ProxyFactory获取将要执行目标方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
如果没有拦截器链直接执行目标方法
如果有就把目标对象,目标方法,拦截器链等 创建一个CglibMethodInvocation并调用proceed()
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
2、拦截器链的触发过程,
如果没有拦截器链执行目标方法,或者当拦截器的索引和拦截器链数组-1大小相等(执行到了最后一个拦截器链),执行目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
链式获取每个拦截器,拦截器执行invoke(),每个拦截器等待下一个拦截器执行完成返回以后再来执行,
链式调用,保证了通知方法和目标方法的执行顺序