在容器创建完成后,会进行刷新容器(refresh()),在容器刷新时会有一步是将Bean定义保存起来
//xxxRegistrar一般是在其中手动注册一些组件,再通过@import导入到容器中;
@EnableAspectJAutoProxy
* @Import(AspectJAutoProxyRegistrar.class)
* 1.(beanName)internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator(组件类型)
* 利用AspectJAutoProxyRegistrar自定义给容器创建bean;
* 给容器中注册一个组件AnnotationAwareAspectJAutoProxyCreator;
* 2.AnnotationAwareAspectJAutoProxyCreator:
*
*
* 继承==>AspectJAwareAdvisorAutoProxyCreator
* ==>AbstractAdvisorAutoProxyCreator
* ==>AbstractAutoProxyCreator
* implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
* 关注后置处理器(在bean初始化前后做的工作)、自动装配BeanFactory
* AbstractAutoProxyCreator.setBeanFactory()
* AbstractAutoProxyCreator有后置处理器的逻辑--postProcessBeforeInstantiation--postProcessAfterInitialization
*
* AbstractAdvisorAutoProxyCreator.setBeanFactory()包含-->initBeanFactory()
*
* AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
*
* 流程:
* 1)、传入配置类,创建ioc容器
* 2)、注册配置类,调用refresh()刷新容器,即是初始化容器
* 3)、registerBeanPostProcessors(beanFactory)注册bean的后置处理器方便拦截bean的创建
* 1.先获取ioc容器中已经定义了的需要创建对象的BeanPostProcessor;其中有一个internalAutoProxyCreator组件,我们只是定义了BeanDefinition,还没有创建对象
* 2.给容器中加其他的BeanPostProcessor
* 3.优先注册实现了PriorityOrdered接口的处理器
* 4.再给容器中注册实现了Ordered接口的处理器
* 5.注册没有实现优先级接口的处理器
* 6.注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中
* 创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
* 1.创建bean的实例
* 2.populateBean:给bean的各种属性赋值
* 3.initializeBean:初始化bean【internalAutoProxyCreator】
* 1.invokeAwareMethods():处理Aware接口的回调,即判断bean实现了Aware接口的哪种接口
* 2.applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
* 3.invokeInitMethods():执行自定义的初始化方法
* 4.applyBeanPostProcessorsAfterInitialization():应用后置处理器的postProcessAfterInitialization()
*
* 4.BeanPostProcessor[AnnotationAwareAspectJAutoProxyCreator]创建成功
*
* 7.把BeanPostProcessor注册到BeanFactory中:->registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors)
* ->beanFactory.addBeanPostProcessor(postProcessor);
* ===========以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程==============
* AnnotationAwareAspectJAutoProxyCreator=>InstantiationAwareBeanPostProcessor(类型)
* 4)、finishBeanFactoryInitialization(beanFactory):完成BeanFactory初始化工作,创建剩下的单实例Bean
* 1.遍历获取容器中所有的bean,依次创建对象getBean(beanName);
* getBean(beanName)=>doGetBean()=>getSingleton()=>createBean();
*
* 2. 创建bean
* 【前面知道AnnotationAwareAspectJAutoProxyCreator是InstantiationAwareBeanPostProcessor类型的】
* 【AnnotationAwareAspectJAutoProxyCreator在创建bean实例之前会被拦截,InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()】
* 1. 先从缓存中获取bean,如果能获取到,说明bean之前被创建过的,直接使用;否则调用createBean()创建bean实例
* 只要创建好的bean都会被缓存起来
* 【BeanPostProcessor是在bean对象创建完成初始化前后调用的】
* 【InstantiationAwareBeanPostProcessor是在创建对象之前先尝试用后置处理器返回对象的】
* 1)、后置处理器先尝试返回对象
* bean = applyBeanPostProcessorsBeforeInstantiation();
* applyBeanPostProcessorsBeforeInstantiation()中先拿到所有的后置处理器,如果是InstantiationAwareBeanPostProcessor类型的,
* 就执行postProcessBeforeInstantiation():会在下章1.1详细讲到
* if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
* 2. createBean():创建bean->AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例
* 1. resolveBeforeInstantiation():解析BeforeInstantiation
* 希望后置处理器能够在此返回一个代理对象,如果能返回就返回,如果不能就继续
* 2. doCreateBean(beanName, mbdToUse, args);真正创建一个bean实例;和3.6流程一样
* 【会循环的验证并创建bean,所以会重复的执行语句】
* AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用:
* 1)、 在每个bean创建之前,会调用postProcessBeforeInstantiation()
* 关注在Aspect配置类中的AspectService和ControllerAspect的创建过程:
* 1)、判断当前bean是否在advisedBeans中(保存了所有需要增强的bean:注解有before...)
* 2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,
* 或者是不是切面(@Aspect)
* 3)、是否需要跳过
* 1.获取候选的增强器(切面里的增强方法)【List<Advisor> candidateAdvisors】
* advisor类型都是InstantiationModelAwarePointcutAdvisor
* 2.始终返回的是false
* 2)、 创建对象
* postProcessAfterInitialization
* 1)、 return wrapIfNecessary(bean, beanName, cacheKey);//包装,如果需要的话
* 1.获取候选的所有增强器(通知方法) :Object[] specificInterceptors;
* getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
* 找到能在当前bean使用的增强器(找哪些通知方法是需要切入当前bean方法的)
* 2.获取bean可用的;findAdvisorsThatCanApply()
* 3.给增强器排序;sortAdvisors()
* 2)、把增强器添加到缓存中
* 3)、如果当前bean需要增强,创建bean的代理对象;createProxy()
* 1.获取所有的增强器(通知方法)
* 2.保存到proxyFactory中<--config
* 3.创建代理对象 spring自动决定
* JdkDynamicAopProxy(config);Jdk的自动代理(当类实现接口时,选择jdk自动代理)
* ObjenesisCglibAopProxy(config);Cglib的自动代理(当类没有实现接口时,选择Cglib代理)
* 4)、给容器中返回使用cglib增强了的代理对象
* 5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法时,代理对象就会执行通知方法的流程
* 3)、目标方法的执行(div())
* 容器中保存了组件的代理对象(Cglib增强后代理对象),这个代理对象中保存了详细信息(比如增强器、对象方法、xxx)
* 1)、CglibAopProxy.intercept();拦截目标方法的执行
* 2)、根据proxyFactory获取将要执行的方法的拦截器链
* List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)
* 1.List<Object> interceptorList保存所有的拦截器 List长度为5
* 一个默认的ExposeInvocationInterceptor,4个增强器
* 2.遍历所有的增强器,将其封装成intercetpor:-->registry.getInterceptors(advisor);
* 3.将增强器转为List<MethodInterceptor>;
* 如果增强器是MethodInterceptor,直接加入到集合中
* 如果不是,用AdvisorAdapter将增强器转为MethodInterceptor
* 转换完成返回MethodInterceptor数组
* 3)、如果没有拦截器链,直接执行目标方法
* 拦截器链(每一个通知方法被包装成方法拦截器,后来方法执行是利用MethodInterceptor机制)
* 4)、如果有拦截器链,把需要执行的目标方法、目标对象、拦截器链等信息传入创建一个CglibMethodInvocation对象,
* 并调用Object retVal = mi.proceed()
* 5)、拦截器链的触发过程
* 1.如果没有拦截器执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
* 2.链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
* 拦截器链的机制,保证通知方法与目标方法的执行顺序(注解积累)
总结:
**类的初始化:**是完成程序执行前的准备工作。在这个阶段,静态的(变量,方法,代码块)会被执行。同时在会开辟一块存储空间用来存放静态的数据。初始化只在类加载的时候执行一次。
类的实例化:是指创建一个对象的过程。这个过程中会在堆中开辟内存,将一些非静态的方法,变量存放在里面。在程序执行的过程中,可以创建多个对象,既多次实例化。每次实例化都会开辟一块新的内存。