转载

invokeBeanFactoryPostProcessors(beanFactory)方法详解

invokeBeanFactoryPostProcessors(beanFactory),根据反射机制从BeanDefinitionRegistry(bean定义注册中心)中找到所有实现了BeanFactoryPostProcessor接口bean,并调用其postProcessBeanFactory()接口方法--来自spring4.x那本书。

调用bean工厂的后处理器。在这个方法中,spring会处理配置类。

下面是这个方法的业务讲解。

invokeBeanFactoryPostProcessors(beanFactory);

{

  1. BeanDefinitionRegistryPostProcessor的后置处理器,这个类型的bean会先在这个流程中被初始化。
  2. 扫描出所有的bean定义。

}

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

{

  1. 拿到所有的bean工厂后处理器。创建两个list,一个放BeanFactoryPostProcessor类型的后处理器,一个放BeanDefinitionRegistryPostProcessor类型的后置处理器。
  2. 创建一个list,用于存放当前准备创建的BeanDefinitionRegistryPostProcessor。 currentRegistryProcessors
  3. 在容器(beanfactory)中获取所有实现了BeanDefinitionRegistryPostProcessor的后处理器。
  4. 遍历从容器中拿到的后处理器,判断是否实现PriorityOrdered接口,true 直接getbean(),并把这个bean加入到processedBeans(已经处理过的bean)中。
  5. 对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
  6. 把刚才2步骤中新加的加入到1步骤的一个BeanDefinitionRegistryPostProcessorlist中。
  7. 进行bean定义的加载 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  8. 调用完成之后currentRegistryProcessors.clear清空。
  9. 去容器中获取BeanDefinitionRegistryPostProcessor

。。。。

和上面步骤类似

}

processConfigBeanDefinitions(registry);
{

  1. 获取ioc容器中目前所有bean定义的名称
  2. 循环遍历,筛选出配置类
  3. 对配置类作排序
  4. 创建一个配置类解析器
  5. 创建一个set candidates,长度为配置类的长度,元素为配置类. 创建一个set保存已经解析过的配置类,长度也为配置类的长度。
  6. do

中间执行的逻辑:

1.解析配置类集合,解析

  1. 获取到解析出的配置类(扫描的bean定义中可能会有新的配置类),重新获得的配置类移除原来的配置类。
  2. 把解析出来的配置类注册到容器中,注册之后把这些配置类添加到已解析的集合中。
  3. 将candidates clear
  4. 判断ioc中的bean定义是否大于原来的bean定义数量,如果大于说明有新的bean定义产生
  5. 获取所有的bean定义,同时创建两个set,一个为原始老的bean定义,一个为已经解析的bean定义,将老的bean定义放到已解析的bean定义set中。
  6. 判断没有被解析的bean定义,加入candidates中。

while(candidates不为空)

}

具体解析配置类得方法

doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)

{

  1. 处理我们的@propertySource注解的
  2. 解析我们的 @ComponentScan 注解 {

}

  1. 处理 @Import annotations
  2. 处理 @ImportResource annotations
  3. 处理 配置类中@Bean方法()
  4. 处理配置类接口的
  5. 处理配置类的父类的

}

把上面步骤2的步骤放到这里来

解析我们的 @ComponentScan 注解 {

  1. 从配置类上获取到所有的 ComponentScan
  2. 遍历解析获取到的ComponentScans{

    1. 将扫描出来的类变为bean定义的集合
    2. 循环遍历处理得到的bean定义集合,判断是不是配置类,如果是直接递归解析。}

}

总结:这个方法调用过后,会把所有的bean定义从class文件中扫描出来,放到factory中。部分bean会先被实例化。

原文  https://segmentfault.com/a/1190000022494389
正文到此结束
Loading...