invokeBeanFactoryPostProcessors(beanFactory),根据反射机制从BeanDefinitionRegistry(bean定义注册中心)中找到所有实现了BeanFactoryPostProcessor接口bean,并调用其postProcessBeanFactory()接口方法--来自spring4.x那本书。
调用bean工厂的后处理器。在这个方法中,spring会处理配置类。
下面是这个方法的业务讲解。
invokeBeanFactoryPostProcessors(beanFactory);
{
- BeanDefinitionRegistryPostProcessor的后置处理器,这个类型的bean会先在这个流程中被初始化。
- 扫描出所有的bean定义。
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
{
- 拿到所有的bean工厂后处理器。创建两个list,一个放BeanFactoryPostProcessor类型的后处理器,一个放BeanDefinitionRegistryPostProcessor类型的后置处理器。
- 创建一个list,用于存放当前准备创建的BeanDefinitionRegistryPostProcessor。 currentRegistryProcessors
- 在容器(beanfactory)中获取所有实现了BeanDefinitionRegistryPostProcessor的后处理器。
- 遍历从容器中拿到的后处理器,判断是否实现PriorityOrdered接口,true 直接getbean(),并把这个bean加入到processedBeans(已经处理过的bean)中。
- 对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
- 把刚才2步骤中新加的加入到1步骤的一个BeanDefinitionRegistryPostProcessorlist中。
- 进行bean定义的加载 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
- 调用完成之后currentRegistryProcessors.clear清空。
- 去容器中获取BeanDefinitionRegistryPostProcessor
。。。。
和上面步骤类似
}
processConfigBeanDefinitions(registry);
{
- 获取ioc容器中目前所有bean定义的名称
- 循环遍历,筛选出配置类
- 对配置类作排序
- 创建一个配置类解析器
- 创建一个set candidates,长度为配置类的长度,元素为配置类. 创建一个set保存已经解析过的配置类,长度也为配置类的长度。
- do
中间执行的逻辑:
1.解析配置类集合,解析
- 获取到解析出的配置类(扫描的bean定义中可能会有新的配置类),重新获得的配置类移除原来的配置类。
- 把解析出来的配置类注册到容器中,注册之后把这些配置类添加到已解析的集合中。
- 将candidates clear
- 判断ioc中的bean定义是否大于原来的bean定义数量,如果大于说明有新的bean定义产生
- 获取所有的bean定义,同时创建两个set,一个为原始老的bean定义,一个为已经解析的bean定义,将老的bean定义放到已解析的bean定义set中。
- 判断没有被解析的bean定义,加入candidates中。
while(candidates不为空)
}
具体解析配置类得方法
doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
{
- 处理我们的@propertySource注解的
- 解析我们的 @ComponentScan 注解 {
}
- 处理 @Import annotations
- 处理 @ImportResource annotations
- 处理 配置类中@Bean方法()
- 处理配置类接口的
- 处理配置类的父类的
}
把上面步骤2的步骤放到这里来
解析我们的 @ComponentScan 注解 {
- 从配置类上获取到所有的 ComponentScan
-
遍历解析获取到的ComponentScans{
- 将扫描出来的类变为bean定义的集合
- 循环遍历处理得到的bean定义集合,判断是不是配置类,如果是直接递归解析。}
}
总结:这个方法调用过后,会把所有的bean定义从class文件中扫描出来,放到factory中。部分bean会先被实例化。
原文
https://segmentfault.com/a/1190000022494389