Spring框架系列之构造方法BeanDefinition扫描原理02

上一篇我们将
AnnotationConfigApplicationContext构造函数的整体流程梳理一遍,今天我们来详细聊聊Spring是如何扫描得到所有需要被管理的Bean信息的,这里用一个专业名词来表示Bean信息叫BeanDefinition,后面我们都简称BD,我们后面会有专门章节来说明BD的类继承关系。

上一篇我们讲到
invokeBeanFactoryPostProcessors是完成扫描的核心方法,那么我们进入该方法来看看:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

关键代码就是
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()),在进一入invokeBeanFactoryPostProcessors方法:

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
   Set<String> processedBeans = new HashSet<>();

   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      // 关键点一、这个beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }else {
            regularPostProcessors.add(postProcessor);
         }
      } 
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
      //关键点二、执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();
			
     boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }else { 
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   } 
  
  //关键点三
   String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   //关键点四、执行BeanFactoryPostProcessor的postProcessBeanFactory方法
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  
   beanFactory.clearMetadataCache();
}

代码有点多,但是归纳起来就做了两件事:第一执行
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,也就是对BeanDefinition进行处理;第二执行BeanFactoryPostProcessor的postProcessBeanFactory方法,执行BeanFactory的后置处理器逻辑。下面我们就来详细说说。

  • 关键点一
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
   if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
      BeanDefinitionRegistryPostProcessor registryProcessor =
            (BeanDefinitionRegistryPostProcessor) postProcessor;
      registryProcessor.postProcessBeanDefinitionRegistry(registry);
      registryProcessors.add(registryProcessor);
   }else {
      regularPostProcessors.add(postProcessor);
   }
}

beanFactoryPostProcessors一般情况下都是空的,除非我们手动调用容器的
addBeanFactoryPostProcessor方法,这里Spring提供了一个扩展点,一般情况下不会使用。

  • 关键点二
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : postProcessorNames) {
      // 
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
      }
   }

首先:

看currentRegistryProcessors这个对象,他的主要作用就是记录当前将要执行的
BeanDefinitionRegistryPostProcessor实例,首先获取到所有的BeanDefinitionRegistryPostProcessor,然后将PriorityOrdered类型的BeanDefinitionRegistryPostProcessor对象添加到currentRegistryProcessors集合中。注意这里获取到的BeanDefinitionRegistryPostProcessor类型对象只有一个ConfigurationClassPostProcessor,那这个类是什么时候添加到BeanFactory里面去的呢?咱们还记得上一篇构造函数里面创建了一个reader对象吗?代码如下:

this.reader = new AnnotatedBeanDefinitionReader(this);


AnnotatedBeanDefinitionReader的构造函数中调用了如下代码:

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

这段代码中创建了五个类型的对象,并将这五个类型对象添加到了BeanFactory中:

1.ConfigurationClassPostProcessor
2.AutowiredAnnotationBeanPostProcessor
3.CommonAnnotationBeanPostProcessor
4.EventListenerMethodProcessor
5.DefaultEventListenerFactory


ConfigurationClassPostProcessor又实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered:

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
      PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {...}

然后执行如下代码:

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

这里开始执行上述的
ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,这个方法就是扫描得到所有的BeanDefinition,由于这里比较复杂,后续我们专门文章来分析,这里先跳过,大家只要知道它的作用即可。

其次:

依次类推,将执行Ordered.class类型的
BeanDefinitionRegistryPostProcessor实例对象。

最后

需要执行普通的
BeanDefinitionRegistryPostProcessor实例对象:

boolean reiterate = true;
while (reiterate) {
   reiterate = false;
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : postProcessorNames) {
      if (!processedBeans.contains(ppName)) {
         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
         reiterate = true;
      }
   }
   sortPostProcessors(currentRegistryProcessors, beanFactory);
   registryProcessors.addAll(currentRegistryProcessors);
   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
   currentRegistryProcessors.clear();
}

但是很奇怪,这里为啥要加个while循环?Spring有病吧?当然没病,人家Spring考虑的周全。这里表示执行上面没有执行的
BeanDefinitionRegistryPostProcessor,而且你在执行过程中,可能会产生新的BeanDefinitionRegistryPostProcessor对象,所以才用个while循环,直到执行完所有的BeanDefinitionRegistryPostProcessor才结束;

执行完后,再执行
BeanDefinitionRegistryPostProcessor实现类的postProcessBeanFactory方法(因为BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor的实现),这里就会执行ConfigurationClassPostProcessor的postProcessBeanFactory方法:

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);


ConfigurationClassPostProcessor的postProcessBeanFactory方法有点特别:

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)) {
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
   }
   enhanceConfigurationClasses(beanFactory);
   beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}


enhanceConfigurationClasses这个方法用于判断是否需要对配置类生成代理对象?什么是配置类?增加了@Configuration注解的类是配置了,它有什么特点呢?凡是在配置类中被@Bean声明的对象都需要代理,所以这里需要对@Configuration类型的对象进行特殊处理;

然后添加
ImportAwareBeanPostProcessor后置处理器,这个是对@import注解进行处理的Bean的后置处理器,后续我们再讲。

  • 关键点三
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
   if (processedBeans.contains(ppName)) {
      // skip - already processed in first phase above
   }else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
   }else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}

这里看代码很简单,就是把所有的BeanFactoryPostProcessor对象分别放到三个集合里面去,然后按优先级先后执行
priorityOrderedPostProcessors、orderedPostProcessorNames、nonOrderedPostProcessorNames中的BeanFactoryPostProcessor对象,但是为什么不像上面的BeanDefinitionRegistryPostProcessor一样处理,而是直接分到三个集合里面呢?这个也很简单,因为执行BeanFactoryPostProcessor方法不会产生新的BeanFactoryPostProcessor对象,所以为了提升效率,直接分组到不同的集合即可。

  • 关键点四

这里就开始执行BeanFactoryPostProcessor的postProcessBeanFactory方法了,先执行
priorityOrderedPostProcessors集合中的,其次执行orderedPostProcessorNames集合中的,最后执行nonOrderedPostProcessorNames集合中的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值