前言
承接上一篇,上一篇我们分析了spring beanFactory如何初始化自身,以及如何如何加载我们xml中配置的bean,在此处我们简单的总结下:
- 1.内部替我们创建了一个DefaultListableBeanFactory,设置序列化id,并提供一些可定制化的设
- 2.通过XmlBeanDefinitionReader找到我们的xml并解析,将我们配置的bean加载注册到我们的facotry容器中
导语
上一篇我们分析了obtainFreshBeanFactory的方法,我们接着看refresh其他操作方法
首先我们从refresh整体方法上看,refresh都有什么样子的操作:
- 允许上下文子类在beanfactory初始化之后修改其内部的beanfactory
- 注册所有BeanPostProcessor
- 初始化事件处理集
- 注册拦截bean创建的所有bean处理器
- 初始化消息源也就是国际化支持的bean
- 注册将ApplicationListener实现为侦听器的bean
- 实例化所有设置单例的bean
等这些操作,接下来,我们从这些方法上一一分析,来了解bean是如何初始化的
refresh的postProcessBeanFactory
首先我们能看到第一个方法postProcessBeanFactory,我们看其实现,看到AbstractApplicatonContext中为空实现,均是由其子类实现,对于AbstractApplicationContext相当于留给子类一个hook方法,这个方法我们延迟放在以后的demo文章尾篇介绍该功能
refresh的invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
从此处我们可以看到大致操作,可分为两部分
- 即首先通过getBeanFactoryPostProcessor获取所有已注册的beanFactoryPostProcessor
- 对获取到的beanFactoryPostProcessor实例化并调用所有
由于PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors的方法过长这里就不贴,我们分析一点贴一点
首先我们一进来就进入了一个if条件判断的方法块中,条件是对BeanDefinitionRegistry的类型进行处理,对于BeanDefinitionRegistry类型的解析,从之前的篇章我们知道,我们的beanfactory为DefaultListableBeanFactory,而DefaultListableBeanFactory自身我们可看到它已实现了BeanDefinitionRegistry接口。
先new了两个容器,一个盛放的是BeanFactoryPostProcessor,另一个盛放的是BeanDefinitionRegistryPostProssessor。
第一步:还是通过遍历所有已注册的BeanFactoryPostProcessor,若为BeanDefinitionRegistryPostProcessor,先调用自身的postProcessBeanDefinitionRegitstry,让后加入到盛放BeanDefinitionRegistryPostProcessor的容器内,若不是BeanDefinitionRegistryPostProcessor,则直接加入到盛放BeanFactoryPostProcessor的容器内
第二步:从我们的beanfactory的getBeansOfType找出所有实现了BeanDefinitionRegistryPostProcessor,通过OrderCcomparator对这些Processor进行排序,然后遍历执行postProcessBeanDefinitionRegistry
-
第三步:invokeBeanFactoryPostProcessors具体方法如下:
即遍历执行每个postProcessor的postProcessBeanFactory方法进行注册
到这里 , 我们看到的均是对BeanDefinitionRegistryPostProcessor的处理,这里也就是对BeanDefinitonRegistryPostProcessor的处理已经全部完毕, 下面是对BeanFactoryPostProcessor的处理
接下来方法是如下:
- 第一步:通过beanFactory的getBeanNamesForType方式查找所有的实现BeanFactoryPostProcessor的类
- 第二步:声明三个容器,一个盛放实现PriorityOrdered接口的容器,一个盛放实现Ordered接口的beanName的容器,还有一个盛放普通postProcessor的beanName的容器
- 第三步:对查找出来的所有BeanFactoryPostProcessor的类进行遍历,分类存放对应的类。而priorityOrderedPostProcessor内存放的BeanFactoryPostProcesor则通过beanfactory的getBean方式获取到
- 第四步:借助OrderComparator对priorityOrderedPostProcessors进行排序,并遍历执行postProcessBeanFactory向beanfactory进行注册
- 第五步:创建一个orderedPostProcessors容器,遍历orderedPostProcessorNames,向创建的orderedPostProcessors存放通过beanfactory的getBean方式获取到PostProcessor
getBean追踪
从上面的getBean处我们了解需要从beanFactory处获取实例bean我们深入看看,最终我们定位到AbstractFactory的doGetBean
首先先去实例化好的bean中去找,如果找到,直接返回
去当前beanfactory中父类factory找,如果能找到父类的factory,则叫父类去返回(有点像classloader的双亲模型呀)
-
开始查看当前要实例化的bean是否依赖于其他的bean,如果依赖,则先实例化依赖的bean,如果依赖的bean还依赖于其他的bean,则接着递归创建
-
如果创建的bean是单例(spring默认单例)接着创建
-
我们跟着createBean看起处理到AbstractAutowireCapableBeanFactory
到这里getbean就为我们准备好了目标的bean
到这里对OrderedPostProcessor的处理,就结束了,紧跟着是对普通PostProcessor的处理,由于一致,这里就不一一分析,将处理代码如下展示:
可能有人好奇OrderComparator的排序是什么样子的,这里我做简单分析:
public int compare(Object o1, Object o2) {
boolean p1 = o1 instanceof PriorityOrdered;
boolean p2 = o2 instanceof PriorityOrdered;
if(p1 && !p2) {
return -1;
} else if(p2 && !p1) {
return 1;
} else {
int i1 = this.getOrder(o1);
int i2 = this.getOrder(o2);
return i1 < i2?-1:(i1 > i2?1:0);
}
}
public static void sort(List> list) {
if(list.size() > 1) {
Collections.sort(list, INSTANCE);
}
}
其实就是借助Collections进行排序,通过比较getOrder实现排序
至此invokeBeanFactoryPostProcessors部分就分析完毕了,此处我们简单做个总结:
整个invokeBeanFactoryPostProcessros围绕着BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor这两个接口,从上面分析可知,BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor均是注册bean用的,但是BeanDefinitionRegistryPostProcessor执行优先于BeanFactoryPostProcessor
操作3种bean对象向beanfactory中注册
1.beanfactory中之前添加的beanFactoryPostProcessor
2.实现了BeanDefinitionRegistryPostProcessor接口的postProcessor
3.实现了BeanFactoryPostProcessor接口的postProcessor
将这三种bean向beanFactory中注册
refresh的registerBeanPostProcessors
registerBeanPostProcessors和invokeBeanFactoryPostProcessros很相像,
首先先看它的具体方法:
也是通过beanFactory的getBeanNamesForType找到所有实现BeanPostProcessor的所有类
- 添加ProcessorChecker这个PostProcessor进beanFactory
很容易,我们发现这个PostProcessor并没有什么特殊操作,只是进行logger.info操作,用来记录一些信息
紧跟着声明了四个容器,和invokeBeanFactoryPostProcessros声明的那三个一致,但是多了一个internalPostProcessors,即用来盛放实现了MergedBeanDefinitionPostProcessor接口的容器(即需要重新注册所有内部BeanPostProcessors)
对priorityOrderedPostProcessor进行分类对于实现了MergedBeanDefinitionPostProcessor就向internalPostProcessor添加一份
-
紧跟着借助OrderComparator排序,然后遍历priorityOrderedPostProcessors进行注册beanPostProcessor
即通过beanfactory的addBeanPostPrcossor想beanfactory进行注册beanPostprocessor
对于orderedPostProcessorNames和nonOrderedPostProcessorNames处理方式和priorityOrderedPostProcessors一致,唯一不同的跟invokeBeanFactoryPostProcessors一样,通过beanFactory的getBean对name进行替换
对于internalPostProcessors的操作,即重新注册所有内部BeanPostProcessors:
OrderComparator.sort(internalPostProcessors);
this.registerBeanPostProcessors(beanFactory, internalPostProcessors);
1.排序
2.注册beanPostProcessor
3.通过beanFactory的addBeanPostProcessor添加BeanPostProcessor
最后通过beanFactory的addBeanPostProcessor添加了一个ApplicationListenerDetector的BeanPostProcessor
可以看到其也是实现了MergedBeanDefinitionPostProcessor,其主要功能是用来检测bean是否是ApplicationListener,如果是判断是否是单例,如果不是单例,那么删除singtonNames中对应的key
由此整个方法也就到这结束了
小小的总结下:
registerBeanPostProcessors与invokeBeanFactoryPostProcessors一致,一个是对BeanPostProcessor的处理,一个是对BeanFactoryPostProcessor的处理,对于BeanPostProcessor而言,对内部的beanPostProcessor重新注册一次
至此对于beanPostProcessor和BeanFactoryPostProcessor,我们就分析到这,我们可以看到spring为我们bean创建等提供了很多由我们自由控制的时机,未避免篇幅太长,后续方法我们下篇继续