invokeBeanFactoryPostProcessors

简介

调用bean工厂的后置处理器

解析

初始化三个集合

//第一步:首先调用BeanDefinitionRegistryPostProcessor的后置处理器
Set<String> processedBeans = new HashSet<>();
//保存BeanFactoryPostProcessor类型的后置
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//保存BeanDefinitionRegistryPostProcessor类型的后置处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

分别保存两种类型的后置处理器

第一个for循环

遍历外部传入的bean工厂后置处理器,当然这里为空,因为我们根本没传,只有是手动调用context.addBeanFactoryPostProcessor(xxx)才会有数据

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
   //判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor
   if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
      //进行强制转化
      BeanDefinitionRegistryPostProcessor registryProcessor =
            (BeanDefinitionRegistryPostProcessor) postProcessor;
      //调用他作为BeanDefinitionRegistryPostProcessor的处理器的后置方法
      registryProcessor.postProcessBeanDefinitionRegistry(registry);
      //添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中
      registryProcessors.add(registryProcessor);
   }
   else {//若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor
      //把当前的后置处理器加入到regularPostProcessors中
      regularPostProcessors.add(postProcessor);
   }
}

获取beandefinitionRegistryPostProcessor

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor

String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

获取容器中BeanDefinitionRegistryPostProcessor的bean后置处理器名称,拿到的是internalConfigurationAnnotationProcessor
第二个for循环

for (String ppName : postProcessorNames) {
    //判断是否实现了PriorityOrdered接口的
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      //同时也加入到processedBeans集合中去
      processedBeans.add(ppName);
   }
}

循环刚刚拿到的bean后置处理器名称,判断是否实现了PriorityOrdered接口,然后将其添加到刚刚创建的缓存集合中,并且加入到processedBeans
注意第5行,调用了getBean,将后置处理器实例化
在这里插入图片描述

对缓存集合cur中的元素进行排序

sortPostProcessors(currentRegistryProcessors, beanFactory);

保存到registryProcessors中

registryProcessors.addAll(currentRegistryProcessors);

执行

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

执行缓存中的后置处理器,这里只有internalConfigurationAnnotationProcessor

ConfigurationAnnotationProcessor

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
   int registryId = System.identityHashCode(registry);
   if (this.registriesPostProcessed.contains(registryId)) {
      throw new IllegalStateException(
            "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
   }
   if (this.factoriesPostProcessed.contains(registryId)) {
      throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + registry);
   }
   this.registriesPostProcessed.add(registryId);
   //真正的解析我们的bean定义
   processConfigBeanDefinitions(registry);
}

调用postProcessBeanDefinitionRegistry方法,这里去调用真正解析processConfigBeanDefinitions,注意registry就是beanFactory
processConfigBeanDefinitions
进行配置类解析的方法,这里简要说明一下该类做了些什么事

  • 首先是获取容器中所有的bean定义名称,然后进行遍历
  • 通过bean定义名称获取bean定义对象,判断是否解析过。进行配置类检查是否标注@Configuration注解还是@bean注解
  • 这里会解析出我们真正的配置类然后加入到配置类集合中
  • 进行order排序, 然后调用parse进行解析配置类
  • 解析完毕之后注册到容器中,并添加到已解析集合中
  • 最后检查是否还有剩余没有解析的配置类,添加到候选集合中进行循环解析
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
   //获取IOC 容器中目前所有bean定义的名称
   String[] candidateNames = registry.getBeanDefinitionNames();

   //循环我们的上一步获取的所有的bean定义信息
   for (String beanName : candidateNames) {
      //通过bean的名称来获取我们的bean定义对象
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      //判断是否有没有解析过
      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
            ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
         if (logger.isDebugEnabled()) {
            logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
         }
      }
      //进行正在的解析判断是不是完全的配置类 还是一个非正式的配置类,將配置类添加集合中
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
         //满足添加 就加入到候选的配置类集合中
         configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
      }
   }

   // 若没有找到配置类 直接返回
   if (configCandidates.isEmpty()) {
      return;
   }

   //对我们的配置类进行Order排序
   configCandidates.sort((bd1, bd2) -> {
      int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
      int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
      return Integer.compare(i1, i2);
   });

   // 创建我们通过@CompentScan导入进来的bean name的生成器
   // 创建我们通过@Import导入进来的bean的名称
   SingletonBeanRegistry sbr = null;
   if (registry instanceof SingletonBeanRegistry) {
      sbr = (SingletonBeanRegistry) registry;
      if (!this.localBeanNameGeneratorSet) {
         BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
         if (generator != null) {
            //设置@CompentScan导入进来的bean的名称生成器
            this.componentScanBeanNameGenerator = generator;
            //设置@Import导入进来的bean的名称生成器
            this.importBeanNameGenerator = generator;
         }
      }
   }

   if (this.environment == null) {
      this.environment = new StandardEnvironment();
   }

   //创建一个配置类解析器对象
   ConfigurationClassParser parser = new ConfigurationClassParser(
         this.metadataReaderFactory, this.problemReporter, this.environment,
         this.resourceLoader, this.componentScanBeanNameGenerator, registry);

   //创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度
   Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
   //创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
   Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
   //do while 会进行第一次解析
   do {
      //真正的解析我们的配置类
      parser.parse(candidates);
      parser.validate();

      //解析出来的配置类
      Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
      configClasses.removeAll(alreadyParsed);

      // Read the model and create bean definitions based on its content
      if (this.reader == null) {
         this.reader = new ConfigurationClassBeanDefinitionReader(
               registry, this.sourceExtractor, this.resourceLoader, this.environment,
               this.importBeanNameGenerator, parser.getImportRegistry());
      }
      //真正的把我们解析出来的配置类注册到容器中
      this.reader.loadBeanDefinitions(configClasses);
      //加入到已经解析的集合中
      alreadyParsed.addAll(configClasses);

      candidates.clear();
      //判断我们ioc容器中的是不是>候选原始的bean定义的个数,原始的是6个后置处理器+配置类,候选的是原始的加上扫描出来的bean
      if (registry.getBeanDefinitionCount() > candidateNames.length) {
         //获取所有的bean定义
         String[] newCandidateNames = registry.getBeanDefinitionNames();
         //原始的老的候选的bean定义
         Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
         Set<String> alreadyParsedClasses = new HashSet<>();
         //赋值已经解析的其他bean,不包含原始的bean
         for (ConfigurationClass configurationClass : alreadyParsed) {
            alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
         }

         for (String candidateName : newCandidateNames) {
            //表示当前循环的还没有被解析过
            if (!oldCandidateNames.contains(candidateName)) {
               BeanDefinition bd = registry.getBeanDefinition(candidateName);
               //判断有没有被解析过
               if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                     !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                  candidates.add(new BeanDefinitionHolder(bd, candidateName));
               }
            }
         }
         candidateNames = newCandidateNames;
      }
   }
   //存在没有解析过的 需要循环解析
   while (!candidates.isEmpty());

   // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
   if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
      sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
   }

   if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
      // Clear cache in externally provided MetadataReaderFactory; this is a no-op
      // for a shared cache since it'll be cleared by the ApplicationContext.
      ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
   }}

这才调用完BeanDefinitionRegistryPostProcessors
现在回到invokeBeanFactoryPostProcessors中,invokeBeanDefinitionRegistryPostProcessors的逻辑才走完,现在再来看我们的beanDefinitionMap中

将cur缓存集合清空

再去容器中获取BeanDefinitionRegistryPostProcessors的bean处理器名称

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

还是只有ConfigurationAnnotationProcessor

遍历得到的bean处理器名称,获取没有处理过的处理器,并且实现了Order接口的

if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class))

当然没有
还是 排序 – >保存集合 --> 执行方法 -->清空缓存 4连操作

进入一个while循环

再次去获取BeanDefinitionRegistryPostProcessors的bean处理器名称,还是只有那一个。再去4连操作一下。

退出循环

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

调用bean工厂后置处理器 区别 之前两次都是调用bean定义注册后置处理器

调用invokeBeanFactoryPostProcessors,这次是从已添加的集合中调用,不为空。注意这里是调用的bean工厂的后置处理器方法,不是bean定义注册的后置处理器方法

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   int factoryId = System.identityHashCode(beanFactory);
   if (this.factoriesPostProcessed.contains(factoryId)) {
      throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + beanFactory);
   }
   this.factoriesPostProcessed.add(factoryId);
   if (!this.registriesPostProcessed.contains(factoryId)) {
      // BeanDefinitionRegistryPostProcessor hook apparently not supported...
      // Simply call processConfigurationClasses lazily at this point then.
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
   }
   //使用cglib对配置类进行动态代理,因为@Bean方法到时候要进行Bean的实例化创建
   enhanceConfigurationClasses(beanFactory);
   beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

这里最后调用的add方法将beanFactory封装为一个ImportAwareBeanPostProcessor方法,作用是什么?
在这里插入图片描述

获取容器中所有的bean工厂后置处理器

String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

创建集合

//保存BeanFactoryPostProcessor类型实现了priorityOrdered
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//保存BeanFactoryPostProcessor类型实现了Ordered接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
//保存BeanFactoryPostProcessor没有实现任何优先级接口的 
List<String> nonOrderedPostProcessorNames = new ArrayList<>();

for循环

依次判断是否实现了PriorityOrdered接口和Ordered接口以及最后没有实现任何优先级的接口
分别加入到不同的集合中。

排序执行

先将实现了PriorityOrdered的进行排序然后执行
再是实现Ordered接口的进行排序执行
最后是没有实现任何接口的
到此结束

最后总结一下

整个过程无非就下面这几步

  • 执行容器中的beanDefinitionRegisterPostProcessors
    • 创建三个集合分别是保存已经执行过的bean定义注册后置处理器、保存bean定义注册的后置处理器和保存bean工厂后置处理器的集合
    • for循环根据beanName从容器中获取后置处理器,然后遍历执行
    • 第一次四连,执行postProcessBeanDefinitionRegistry。解析我们的配置类,实现priorityOrdered接口的
    • 第二次去获取bean定义注册后置处理器,然后第二次四连,实现了ordered接口的
    • 进入while循环,第三次去获取bean定义注册后置处理器
    • 如果while循环并没有得到没有被处理过的处理器,那就跳出循环
    • 调用保存bean定义注册后置处理器集合中的bean工厂后置处理器,执行这里会对配置类进行动态代理,并将beanfactory包装为一个ImportAwareBeanPostProcessor放入beanfactory的后置处理器中
    • 调用保存bean工厂后置处理器集合中的bean工厂后置处理器
  • 执行容器中的beanFactoryPostProcessors
    • 获取容器中bean工厂后置处理器
    • 创建三个集合,保存实现priorityOrdered接口的处理器、实现了Ordered接口的处理器和没有实现任何接口的处理器集合
    • 遍历后置处理器,跳过已经执行过的。分别将不同接口的处理器加入对应集合中
    • 按照priority、ordered和没有实现优先级接口的处理器顺序,依次调用执行

关于ConfigurationClassPostProcessor

在这里插入图片描述

这个类是内置的6个后置处理器之一,作用是在帮助解析配置类
在整个invokeBeanFactoryPostProcessors的执行过程中,该类有如下的调用

  • 首先是在第一次获取后置处理器时,得到BeanDefinitionRegistryPostProcessor的实现类后置处理器,执行其postProcessBeanDefinitionRegistry方法。这里将所有的bean定义注册
  • 然后在whilie循环结束之后,调用其postProcessBeanFactory方法创建配置类的动态代理

后置处理器的执行总结

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值