prepareBeanFactory,执行BeanFactoryPostProcessors,注册BeanPostProcessors

本系列大量参考Spring IOC 容器源码分析【死磕 Spring】—– IOC 总结程序员囧辉的CSDN

文章内容如下:
1.AbstractApplicationContext#refresh()
//设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,
//手动注册几个特殊的 bean(这边简单提一下注册的AspectJ相关)
2. AbstractApplicationContext#prepareBeanFactory(beanFactory) 
// 空方法,交由子类实现。
3.AbstractApplicationContext#postProcessBeanFactory()
//调用IOC容器初始化后的后置方法
4.AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory) 
  //根据顺序执行BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 接口的扩展类方法
  4.1 PostProcessorRegistrationDelegate #invokeBeanFactoryPostProcessors 
    4.1.1 几个参数的介绍
    4.1.2 BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor的区别
    4.1.3 总结PostProcessorRegistrationDelegate中的执行逻辑
    4.1.4 BeanDefinitionRegistryPostProcessor的应用场景
//注册 BeanPostProcessor 的实现类
5.AbstractApplicationContext#registerBeanPostProcessors 
  //注册 BeanPostProcessor 的真正实现类,会把的BeanPostProcessor实现类放到缓存中
  5.1PostProcessorRegistrationDelegate #registerBeanPostProcessors(beanFactory,applicationContext) 
    // 遍历 BeanPostProcessor 数组,注册
    5.1.1PostProcessorRegistrationDelegate#registerBeanPostProcessors 
     //真正注册代码逻辑
     5.1.1.1 AbstractBeanFactory#addBeanPostProcessor 
6.Spring的BeanFactoryPostProcessor和BeanPostProcessor区别

上一篇说到,Bean 容器实例化完成后,这边重新贴一下refresh方法的代码,继续往下看

1. AbstractApplicationContext#refresh()

public void refresh() throws BeansException, IllegalStateException {
   // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
   synchronized (this.startupShutdownMonitor) {

      // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
      prepareRefresh();

      // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
      // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
      // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
      // 这块待会会展开说
      prepareBeanFactory(beanFactory);

      try {
         // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
         // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】

         // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
         // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
         postProcessBeanFactory(beanFactory);
         // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
         invokeBeanFactoryPostProcessors(beanFactory);

         // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
         registerBeanPostProcessors(beanFactory);

         // 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
         initMessageSource();

         // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
         initApplicationEventMulticaster();

         // 从方法名就可以知道,典型的模板方法(钩子方法),
         // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
         onRefresh();

         // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
         registerListeners();

         // 重点,重点,重点
         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         finishBeanFactoryInitialization(beanFactory);

         // 最后,广播事件,ApplicationContext 初始化完成
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // 把异常往外抛
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

上一篇介绍到obtainFreshBeanFactory()方法,今天接着来看 prepareBeanFactory(beanFactory)做了什么。

2.AbstractApplicationContext#prepareBeanFactory(beanFactory) 设置BeanFactory的必要属性

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

          //BeanFactory 需要加载类,也就需要类加载器,
          // 这里设置为加载当前 ApplicationContext 类的类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
        // 设置 BeanFactory 的表达式语言处理器,Spring3 增加了表达式语言的支持
        // 默认可以使用 #{bean.xxx} 的形式来调用相关属性
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        // 添加 BeanFactory 的属性编辑器 ResourceEditorRegistrar 对象
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
 // 添加一个 BeanPostProcessor,这个 processor 比较简单:
   // 实现了 Aware 接口的 beans 在初始化前后,这个 processor 负责回调,
   // 这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
   // 注意:它不仅仅回调 ApplicationContextAware,
   //   还会负责回调 EnvironmentAware、ResourceLoaderAware 等,看下源码就清楚了

        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 
  // 下面几行的意思就是,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,
   // Spring 会通过其他方式来处理这些依赖。
        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 赋值,如果有 bean 依赖了以下几个,会注入这边相应的值,
    * 之前我们说过,"当前 ApplicationContext 持有一个 BeanFactory",这里解释了第一行。
    * ApplicationContext 还继承了 ResourceLoader、ApplicationEventPublisher、MessageSource
    * 所以对于这几个依赖,可以赋值为 this,注意 this 是一个 ApplicationContext
    * 那这里怎么没看到为 MessageSource 赋值呢?那是因为 MessageSource 被注册成为了一个普通的 bean
    */
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Register early post-processor for detecting inner beans as ApplicationListeners.

//该BeanPostProcessor检测那些实现了接口ApplicationListener的bean,
//在它们创建时初始化之后,将它们添加到应用上下文的事件多播器上;
//并在这些ApplicationListener bean销毁之前,将它们从应用上下文的事件多播器上移除。
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // 检查容器中是否包含名称为loadTimeWeaver的bean,实际上是增加Aspectj的支持
        // AspectJ采用编译期织入、类加载期织入两种方式进行切面的织入
        // 类加载期织入简称为LTW(Load Time Weaving),通过特殊的类加载器来代理JVM默认的类加载器实现
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            // 添加BEAN后置处理器:LoadTimeWeaverAwareProcessor
            // 在BEAN初始化之前检查BEAN是否实现了LoadTimeWeaverAware接口,
            // 如果是,则进行加载时织入,即静态代理。
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

   /**
    * 从下面几行代码我们可以知道,Spring 往往很 "智能" 就是因为它会帮我们默认注册一些有用的 bean,
    * 我们也可以选择覆盖
    */

// 如果没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
 // 如果没有定义 "systemProperties" 这个 bean,那么 Spring 会 "手动" 注册一个
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
// 如果没有定义 "systemEnvironment" 这个 bean,那么 Spring 会 "手动" 注册一个
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }
//省略其他代码
}

如这个方法名所说的,这个方法里也是设置了各个beanFactory所需的功能,这边还检查了一个叫loadTimeWeaverbean,这个是AspectJ相关bean

这里简单提一下Spring AOPAspectJ的区别
AspectJ在Spring中的使用

image.png

3.AbstractApplicationContext#postProcessBeanFactory

在执行完prepareBeanFactory后,回到refresh方法,往下执行到了postProcessBeanFactory方法,值得注意的是,这个是一个空方法,需要子类实现。
注意是子类,与我们所知的实现BeanFactoryPostProcessor那个扩展接口不是一个东西。

4.AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory) 调用IOC容器初始化后的后置方法

如果子类没有实现,接着调用invokeBeanFactoryPostProcessors方法,

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 执行 BeanFactoryPostProcessor 的钩子方法
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());


        //  AOP 相关
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

这里有一个getBeanFactoryPostProcessors()方法用来获取ApplicationContext里的beanFactoryPostProcessors,而这个对象是何时注入的我们有机会会在其他篇章说明。这里暂只需要知道有这个值。况且在我们以ClassPathXmlApplicationContext讲解时也没有这个值注入的场景,这个值在ClassPathXmlApplicationContext中其实是为空的。
(注意!!:这个beanFactoryPostProcessors指的是通过硬编码添加到ApplicationContext这个容器里来的,不是指我们配置的那些,我们配置的那些通过简单的getBeanFactoryPostProcessors是取不到的,在下面介绍的invokeBeanFactoryPostProcessors会提到,通过这些扩展接口拿到实现类才能取到。)

  public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
      return this.beanFactoryPostProcessors;
  }

4.1 PostProcessorRegistrationDelegate #invokeBeanFactoryPostProcessors 根据顺序执行BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 接口的扩展类方法

继续往里面进入看看invokeBeanFactoryPostProcessors做了什么,在这里先提前说明一下,这个方法虽然比较长,但是很多都是极其相似的逻辑,搞懂一个情况其他的都懂了,如果几个变量看的比较晕,可以把这串代码拷贝到IDEA上看,点击一个变量后,这个变量被用到的位置都会以浅色背景标识出来。比如这样

image.png

final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        // 已经执行的 BeanDefinitionRegistryPostProcessor 的集合
        Set<String> processedBeans = new HashSet<>();

        // 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
        // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // 强转为 BeanDefinitionRegistry 对象
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 用于存放普通的BeanFactoryPostProcessor类型的后置处理器
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // regular 翻译为常规。
            // 保存BeanDefinitionRegistryPostProcessor类型的后置处理器
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            //2.首先处理入参中的beanFactoryPostProcessors
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                //判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    //强转为 BeanDefinitionRegistryPostProcessor 对象
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
                    //  对于 BeanDefinitionRegistryPostProcessor 类型,在 BeanFactoryPostProcessor 的基础上还有自定义的方法
                    //直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    // 添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合(用于最后执行postProcessBeanFactory方法)
                    registryProcessors.add(registryProcessor);
                } else {
                    //若没有实现BeanDefinitionRegistryPostProcessor接口,那么他就是BeanFactoryPostProcessor
                    // 把当前的后置处理器加入到regularPostProcessors中
                    regularPostProcessors.add(postProcessor);
                }
            }


            // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();


            //3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
            //找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
            for (String ppName : postProcessorNames) {
                //判断是否实现了PriorityOrdered接口的
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    //显示的调用getBean()的方式获取出对应的bean实例,然后加入到currentRegistryProcessors集合中去
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //将要被执行的加入processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            //  添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合(用于最后执行postProcessBeanFactory方法)
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕后, 清空currentRegistryProcessors
            currentRegistryProcessors.clear();


            //4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类
            //找出所有实现BeanDefinitionRegistryPostProcessor接口的类,
            // 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
            //注意,这里的内容与步骤3极其类似,就简略注释了
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 校验是否实现了Ordered接口,并且还未执行过
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            // 先排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到 registryProcessors 中(用于最后执行postProcessBeanFactory方法)
            registryProcessors.addAll(currentRegistryProcessors);
            // 后执行
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 清空 currentRegistryProcessors
            currentRegistryProcessors.clear();


            //5.调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor,与3.4.也是差不多的
            //定义一个重复处理的开关变量 默认值为true
            boolean reiterate = true;
            //第一次就可以进来
            while (reiterate) {
                //进入循环马上把开关变量给改为false,顺带一提,refresh是synchronized修饰的,不必在意多线程情况
                reiterate = false;
                // 获得配置的,BeanDefinitionRegistryPostProcessor 数组
                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); // 添加 processedBeans 中
                        reiterate = true;
                    }
                }
                // 先排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 添加到 registryProcessors 中(用于最后执行postProcessBeanFactory方法)
                registryProcessors.addAll(currentRegistryProcessors);
                // 执行 currentRegistryProcessors
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 清空 currentRegistryProcessors
                currentRegistryProcessors.clear();
            }


            //6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            // (BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            //7.调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {

            //若当前的beanFactory没有实现了BeanDefinitionRegistry 直接调用入参beanFactoryPostProcessors接口的方法进行后置处理
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
        // 下面开始处理容器中的所有BeanFactoryPostProcessor

        // 8.找出所有实现BeanFactoryPostProcessor接口的类
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 用于存放普通BeanFactoryPostProcessor的beanName
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            // 跳过已经执行过的
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 添加实现了PriorityOrdered接口的BeanFactoryPostProcesso,并在此一举做好了实例化
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                // 添加剩下的普通BeanFactoryPostProcessor的beanName
                nonOrderedPostProcessorNames.add(ppName);
            }
        }


        //9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor,
        // 这里的处理与上面的步骤3、4、5处理也极其类似

        // 对priorityOrderedPostProcessors排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        //遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);


        //10.调用所有实现Ordered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : orderedPostProcessorNames) {
            //获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 先排序
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 后执行
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        //11.调用所有剩下的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            //获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        //清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
        // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
        beanFactory.clearMetadataCache();
    }
//省略其他代码
}

4.1.1 几个参数的介绍

  • 入参 beanFactoryPostProcessors:拿的是 AbstractApplicationContext类的 beanFactoryPostProcessors 属性值,也就是在之前已经添加到 beanFactoryPostProcessors中的 BeanFactoryPostProcessor

  • BeanDefinitionRegistryPostProcessor 接口实现类:实现了 BeanDefinitionRegistryPostProcessor 接口,并且注册到 Spring IoC容器中。

  • 常规 BeanFactoryPostProcessor 接口实现类:实现了 BeanFactoryPostProcessor 接口,并且注册到 Spring IoC容器中。

4.1.2 BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor的区别

BeanDefinitionRegistryPostProcessor 接口继承了BeanFactoryPostProcessor ,这里对于
BeanDefinitionRegistryPostProcessor 接口,既可以获取和修改BeanDefinition的元数据,也可以实现 BeanDefinition 的注册、移除等操作(这个接口主要也是为了增减BeanDefinition,虽然他也可以改变,但是改变交由BeanFactoryPostProcessor来做会使目的更明确)。

这两个接口的简单介绍可参考该链接:Spring处理器及其相关的使用场景

4.1.3 总结PostProcessorRegistrationDelegate中的执行逻辑

概括来说,对于执行顺序,
postProcessBeanDefinitionRegistry 方法优于postProcessBeanFactory方法
BeanDefinitionRegistryPostProcessor的实现类优于BeanFactoryPostProcessor的实现类,
BeanFactory早期被硬编码注入的参数优于我们自己实现的接口
实现了 PriorityOrdered接口的 优于 实现了Ordered接口的(同实现需要比较Order值) 优于两者都没实现的

以上的比较顺序分先后。

详细执行顺序如下
第一优先级:入参beanFactoryPostProcessors中的 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry 方法(2.)。
第二优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanDefinitionRegistry方法(3.)。
第三优先级:BeanDefinitionRegistryPostProcessor接口实现类,并且实现了 Ordered接口,调用 postProcessBeanDefinitionRegistry方法(4.)。
第四优先级:除去第二优先级和第三优先级,剩余的 BeanDefinitionRegistryPostProcessor接口实现类,调用 postProcessBeanDefinitionRegistry方法(5.)。

第五优先级:所有 BeanDefinitionRegistryPostProcessor接口实现类,调用 postProcessBeanFactory 方法(6.)。
第六优先级:入参 beanFactoryPostProcessors中的常规 BeanFactoryPostProcessor,调用 postProcessBeanFactory方法(7.)。
第七优先级:常规 BeanFactoryPostProcessor接口实现类,并且实现了PriorityOrdered接口,调用 postProcessBeanFactory方法(9.)。
第八优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 Ordered接口,调用 postProcessBeanFactory 方法(10.)。
第九优先级:除去第七优先级和第八优先级,剩余的常规 BeanFactoryPostProcessor接口的实现类,调用 postProcessBeanFactory方法(11.)。

参考: Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解

4.1.4 BeanDefinitionRegistryPostProcessor的应用场景

这里还值得说一下BeanDefinitionRegistryPostProcessor的一个应用场景——Mybatis

我们通常在使用 Mybatis +Spring 时,经常用到的 org.mybatis.spring.mapper.MapperScannerConfigurer 就是一个BeanDefinitionRegistryPostProcessorMapperScannerConfigurerpostProcessBeanDefinitionRegistry方法中进行了一些操作,主要是:扫描 basePackage 指定的目录,将该目录下的类(通常是 DAO/MAPPER 接口)封装成 BeanDefinition 并加载到 BeanFactory 中。因此,我们可以看到我们项目中的 DAO(MAPPER)接口,通常都没有使用注解或XML的方式注册到 Spring容器,但是我们还是可以在Service 服务中,使用 @Autowire 注解来将其注入到Service中,就是因为这个原因。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--basePackage指定要扫描的包,在此包之下的映射器都会被搜索到。可指定多个包,包与包之间用逗号或分号分隔-->
    <property name="basePackage" value="com.joonwhee.open.demo.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

image.png

5.AbstractApplicationContext#registerBeanPostProcessors 注册 BeanPostProcessor 的实现类

说完了invokeBeanFactoryPostProcessors(),接下来说refresh方法里的调用的下一个方法registerBeanPostProcessors(),这个方法用于
注册拦截 Bean 创建的 BeanPostProcessor,将所有实现了BeanPostProcessor接口的类加载到 BeanFactory 中。注意这里只是注册,真正的调用在 #getBean(...) 的时,即Bean 创建的时候。

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

显然调用的逻辑不在这,继续往下看.

5.1PostProcessorRegistrationDelegate #registerBeanPostProcessors(beanFactory,applicationContext) 注册 BeanPostProcessor 的真正实现类,会把的BeanPostProcessor实现类放到缓存中

final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        // 1.找出所有实现BeanPostProcessor接口的类
        // 这些 beanName 都已经全部加载到容器中去,但是没有实例化
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        // 记录所有的beanProcessor数量
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        // 2.注册 BeanPostProcessorChecker,它主要是用于在 BeanPostProcessor 实例化期间记录日志
        // 当 Spring 中高配置的后置处理器还没有注册就已经开始了 bean 的实例化过程,这个时候便会打印 BeanPostProcessorChecker 中的内容
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        //3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
        // priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        // orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        //4.遍历postProcessorNames, 将BeanPostProcessors按上述的四个定义的变量区分开
        for (String ppName : postProcessorNames) {
            //按 PriorityOrdered 接口区分
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 调用 getBean 获取 bean 实例对象
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                //如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    //则将ppName对应的Bean实例添加到internalPostProcessors
                    internalPostProcessors.add(pp);
                }
                //按 Ordered 接口区分
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                //剩下的就是什么都没实现,普通的BeanPostProcessor
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 5.注册实现PriorityOrdered接口的BeanPostProcessors
        // 对priorityOrderedPostProcessors进行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 注册priorityOrderedPostProcessors
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // 6.注册实现Ordered接口的BeanPostProcessors
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        //拿到ppName对应的BeanPostProcessor实例对象
        for (String ppName : orderedPostProcessorNames) {
            //将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                //如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
                //则将ppName对应的Bean实例添加到internalPostProcessors
                internalPostProcessors.add(pp);
            }
        }
        // 对orderedPostProcessors进行排序
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 注册orderedPostProcessors
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);


        // 7.注册所有常规的BeanPostProcessors(过程与6类似)
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        // 注册,无需排序(因为没有实现排序的接口嘛)
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
        
        //8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
        // 对internalPostProcessors进行排序
        sortPostProcessors(internalPostProcessors, beanFactory);
        // 注册internalPostProcessors
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        //9.重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
//省略其他代码
}

方法的逻辑与上面介绍的invokeBeanFactoryPostProcessors也很类似,排序也是一样的逻辑,上面那个方法看懂了这个读下来会没有丝毫停滞,所以就不作详细介绍了。有一点不同就是,上面介绍的invokeBeanFactoryPostProcessors 方法会直接调用 BeanFactoryPostProcessor 实现类的方法,而 此次介绍的
registerBeanPostProcessors 方法只是将 BeanPostProcessor 实现类注册到 BeanFactorybeanPostProcessors 缓存中。

5.1.1PostProcessorRegistrationDelegate#registerBeanPostProcessors 遍历 BeanPostProcessor 数组,注册

注册的方法代码如下:

    private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        // 遍历 BeanPostProcessor 数组,注册
        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }

接着往下调用,调用到了AbstractBeanFactory#addBeanPostProcessor

5.1.1.1 AbstractBeanFactory#addBeanPostProcessor 真正注册代码逻辑

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 1.如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
    this.beanPostProcessors.remove(beanPostProcessor);
    // 2.将beanPostProcessor添加到beanPostProcessors缓存
    this.beanPostProcessors.add(beanPostProcessor);
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        // 3.如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
        // 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        // 4.如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
        // 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
        this.hasDestructionAwareBeanPostProcessors = true;
    }
}

该方法作用就是将BeanPostProcessor 添加到beanPostProcessors缓存,这边的先移除再添加,主要是起一个排序的作用。而hasInstantiationAwareBeanPostProcessorshasDestructionAwareBeanPostProcessors 变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessorsDestructionAwareBeanPostProcessor,在之后的 IoC 创建过程会用到这两个变量,这边先有个印象。

6.Spring的BeanFactoryPostProcessor和BeanPostProcessor区别

Spring的BeanFactoryPostProcessor和BeanPostProcessor区别

1.BeanPostProcessor实现类具体的 “出场时机” 在创建 bean 实例时,执行初始化方法前后。postProcessBeforeInitialization 方法在执行初始化方法前被调用,postProcessAfterInitialization 方法在执行初始化方法后被调用。

2.BeanPostProcessor实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrderedOrdered接口来调整自己的优先级。

3.registerBeanPostProcessors 方法和 invokeBeanFactoryPostProcessors 也会触发 bean 实例的创建(这两个方法里都会调用到getBean方法,这个是bean创建的主要方法)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容