spring系列10:BeanFactory 后置处理器的调用

前言

在 prepareRefresh 方法之后,Spring 开始执行与 BeanFactory 相关操作,其中一个非常重要的点就是执行 BeanFactory 后置处理器。

BeanFactory 后置处理器是怎么开始执行?又为什么在这里调用 BeanFactory 后置处理器?

源码中会告诉我们答案。

obtainFreshBeanFactory()

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

根据方法名称,这里是获得 BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

继续跟进 refreshBeanFactory();

// GenericApplicationContext

@Override
protected final void refreshBeanFactory() throws IllegalStateException {
   if (!this.refreshed.compareAndSet(false, true)) {
      throw new IllegalStateException("GenericApplicationContext does not support                   multiple refresh attempts: just call 'refresh' once");
   }
   this.beanFactory.setSerializationId(getId());
}

使用 CAS 改变 refreshed 标记,再给 BeanFactory 设置一个序列化 ID。

@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
   return this.beanFactory;
}

返回 BeanFactory,从代码可以看出,容器早已初始化一个 BeanFactory,并赋值到beanFactory属性中,那么 BeanFactory 是在哪实例化的呢?

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

AnnotationConfigApplicationContext 的父类 GenericApplicationContext 的无参构造方法做了这重要的一步,并且默认是一个 DefaultListableBeanFactory

prepareBeanFactory()

得到 BeanFactory 后,Spring 将 BeanFactory 传入到 prepareBeanFactory()方法中。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

   // 设置classLoader(用于加载bean)
   beanFactory.setBeanClassLoader(getClassLoader());
   // 设置表达式解析器 StandardBeanExpressionResolver(解析bean定义中的一些表达式)
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   // 添加属性编辑注册器(注册属性编辑器)
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));


   // 添加一个名为 ApplicationContextAwareProcessor 的 Bean 的后置处理器 
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   // 下面六个接口全部交给前面添加的后置处理器处理
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // 设置特殊类型对应的bean。
   // beanFactory 对应刚刚获取的 BeanFactory
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // 添加一个 ApplicationListenerDetector 的 BeanPostProcessor,用于解析实现了ApplicationListener接口的bean
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // 如果包含 loadTimeWeaver,则添加一个 LoadTimeWeaverAwareProcessor 的 BeanPostProcessor,与 AOP 有关,同时还设置 ClassLoader
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // 注册默认需要的 bean
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

前面设置 classLoaderSpring 添加一行注释:

Tell the internal bean factory to use the context's class loader etc.

内部的 BeanFactory 使用容器的类加载器,难道自定义的 BeanFactory 使用的是别的类加载器?

在添加一个名为 ApplicationContextAwareProcessor 的 Bean 的后置处理器后,Spring 把实现这六个接口(EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware)中任意一接口的 Bean,交由该后置处理器解析。

之后还添加了两个 Bean 的后置处理器后:ApplicationListenerDetectorLoadTimeWeaverAwareProcessor。一共在这里添加了三个 Bean 的后置处理器,具体作用后面解析。

最后就是注册一些容器默认所需的 Bean

postProcessBeanFactory()

空方法,Spring 扩展点,跳过。

invokeBeanFactoryPostProcessors()

重点了来了。

还记得前面讲过两个接口吗,BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessorSpring 在准备好所需的工作之后,就开始实例化这实现了这两个接口的 Bean,并调用里面唯一的方法。

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()));
   }
}

下面一部分与 AOP 有关,不是这篇的重点,直接跟进第一行代码。

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

调用一个静态方法也叫 invokeBeanFactoryPostProcessors,传入了当前的 BeanFactory getBeanFactoryPostProcessors()从 BeanFactory 拿出所有已注册并且已经实例化的 BeanFactory 后置处理器(什么时候注册的前面已单独拿一片文章讲过,注意虽然注册,但是没有实例化),正常情况这里应该是空。

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // 新建一个 Set 集合,保存所有已经实例化过的 BeanFactoryPostProcessor
   Set<String> processedBeans = new HashSet<>();

   // 判断 beanFactory 是否继承或实现 BeanDefinitionRegistry
   if (beanFactory instanceof BeanDefinitionRegistry) {
      // 把 beanFactory 强转为 BeanDefinitionRegistry
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      // 新建一个保存常规 BeanFactoryPostProcessor 集合
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      // 保存 BeanDefinitionRegistryPostProcessor 接口
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
      // 遍历从 BeanFactory 拿出所有已注册并且已经实例化的 BeanFactory 后置处理器
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         // 判断是否实现了 BeanDefinitionRegistryPostProcessor 接口
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            // 强转为 BeanDefinitionRegistryPostProcessor
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            // 执行 BeanDefinitionRegistryPostProcessor 接口中的 postProcessBeanDefinitionRegistry 方法
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            // 执行后添加到 registryProcessors
            registryProcessors.add(registryProcessor);
         }
         else {
            // 如果未实现 BeanDefinitionRegistryPostProcessor 接口则添加到 regularPostProcessors
            regularPostProcessors.add(postProcessor);
         }
      }


      // 新建一个保存符合当前检测类型后置处理器集合
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();


      // 从 beanFactory 找出所有实现了 BeanDefinitionRegistryPostProcessor 接口的 BeanDefinition
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

      // 遍历找出的 BeanDefinition
      for (String ppName : postProcessorNames) {
         // 判断该 BeanDefinition 是否还实现了 PriorityOrdered 接口
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 根据 BeanDefinition 实例化 Bean,添加到 currentRegistryProcessors
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            // 添加到 processedBeans
            processedBeans.add(ppName);
         }
      }
      // 对实例化好的后置处理器排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      // 添加已实例化好的后置处理器到 registryProcessors
      registryProcessors.addAll(currentRegistryProcessors);
      // 执行符合当前规则所有后置处理器 postProcessBeanDefinitionRegistry 方法
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      // 清空当前规则后置处理器集合,后面还会用到
      currentRegistryProcessors.clear();


      // 与前面相差不大,这里筛选出同时继承了 Ordered 接口的后置处理器
      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();


      // 执行之后添加实现 BeanDefinitionRegistryPostProcessor 接口的 Bean
      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();
      }


      // 执行实现 BeanFactoryPostProcessor 接口中的 postProcessBeanFactory 
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {

      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // 选出所有实现了 BeanFactoryPostProcessor 接口的后置处理器
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);



   // 同时实现了 PriorityOrdered 接口保存到 priorityOrderedPostProcessors 集合
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   // 同时实现了 Ordered 接口保存到 orderedPostProcessorNames 集合
   List<String> orderedPostProcessorNames = new ArrayList<>();
   // 上面两个接口都没事实现保存到 nonOrderedPostProcessorNames
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
        
      }
      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);
      }
   }

   // 排序
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // 实例化同时实现 Ordered 接口,并执行方法
   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();
}

上面注释只是简单简述一下代码意义,想要看懂上面代码还需细品。

分析

总体来看,invokeBeanFactoryPostProcessors 方法只是调用接口中的方法,细分可以分为,第一个if判断是执行 BeanDefinitionRegistryPostProcessor 接口中的 postProcessBeanDefinitionRegistry 方法,下面部分是执行 BeanFactoryPostProcessor 接口中的 postProcessBeanFactory

postProcessBeanDefinitionRegistry的执行

private static void invokeBeanDefinitionRegistryPostProcessors(
      Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

   for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanDefinitionRegistry(registry);
   }
}

1、为什么执行这个方法要判断 beanFactory 是否实现了 BeanDefinitionRegistry

一个完整的 beanFactory 不可能单单只实现了这一个接口 BeanDefinitionRegistry,这个接口只是 beanFactory 的一部分,在这里强转为 BeanDefinitionRegistry,说明 Spring 在这里只要这个接口里面的方法,因为 postProcessBeanDefinitionRegistry 这个方法 Spring 只希望程序员用来动态注册 BeanDefinition,所以你会看到 BeanDefinitionRegistry 接口里的方法都是有关 BeanDefinitionRegistry 增删改查,Spring 开发者也不希望你在这里调用 beanFactory 的其他方法。同时还有一层意思,beanFactory 只有实现了 BeanDefinitionRegistry 接口才支持 动态注册 BeanDefinition

2、四个集合 processedBeansregularPostProcessorsregistryProcessors ,currentRegistryProcessors 的作用?

processedBeans 是保存已经实例化后的 BeanFactory 后置处理器,为什么要做记录,下面讲。

regularPostProcessors 是保存只实现 BeanFactoryPostProcessor 接口的后置处理器。

registryProcessors 保存所有已经实例化,并且没有调用接口对应方法的后置处理器。

currentRegistryProcessorsSpring 只保存符合当前有条件的后置处理器。

3、后置处理器的排序

宏观上,Spring 直接按照是否实现了指定接口顺序执行,PriorityOrdered 先,后 Ordered,最后是两个接口都没实现的。在微观里,即使实现了这两个接口,Spring 还是会调用 sortPostProcessors 方法对后置处理器再一次排序。

4、正常情况下,传入参数 beanFactoryPostProcessors 为空,为什么最开始要遍历执行。

这部分个人觉得是对应了前面 refresh 中的空方法 postProcessBeanFactory,在这个地方,可能程序员会添加实例化 BeanFactory 后置处理器,而在这里,主要是调用未实例化的 BeanFactory 后置处理器的方法。

5、下面为什么会出现while循环

前面说了 postProcessBeanDefinitionRegistry 是动态注册 BeanDefinition,这个 BeanDefinition 可能来源于程序员主动添加,也可能来源于配置文件,Spring 开发者并不知道会不会超预期,while循环保证每个 BeanFactory 后置处理器都能调用,并且这个新加入的 BeanFactory 后置处理器,前面并没有调用,所以这里也用到了 processedBeans 集合。

6、后置处理器是调用 getBean 方法来实例化的,该方法是 Spring 的核心方法之一,在这里可以简单理解为实例化一个 Bean

postProcessBeanFactory的执行

private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanFactory(beanFactory);
   }
}

1、一开始全部找出来所有实现 BeanFactoryPostProcessor 接口的后置处理器,其中包括前面已经执行过的后置处理器(BeanDefinitionRegistryPostProcessors 是 BeanFactoryPostProcessors 的子接口),所以这里又用到 processedBeans,在这里该集合,又多了一层意义,不只是已经实例化后的后置处理器,还是已经执行过的后置处理器。

2、这里执行也会排序,同样是根据前面两个接口来排序。

总结

先调用实现了 BeanDefinitionRegistryPostProcessor 接口里的方法,保证所有 Bean 已注册到容器中,后调用实现了 BeanFactoryPostProcessor 接口里的方法,对 BeanFactory 进行修改,同时,BeanFactory 后置处理器是有调用顺序。

这里是 Spring 很重要的一个扩展点。通过配置配置的 Bean 都会被注册都容器中,同时程序员配置的 BeanFactory 后置处理器或是在 BeanFactory 后置处理器添加的后置处理器都会在这里执行。动态注册 BeanDefinition 是在这里完成的,同时程序员也可以实现相关接口在这里对已注册 BeanDefinition 进行修改。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值