一、概述

  • 本方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。
  • BeanFactoryPostProcessor 接口是 Spring 初始化BeanFactory时对外暴露的扩展点,Spring IoC容器允许BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
  • BeanDefinitionRegistryPostProcessor继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。(关于BeanDefinitionRegistryPostProcessor更加详细一些的介绍可以查看这边博客中的内容:https://www.cnblogs.com/tdyang/p/12088554.html
  • 特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。

注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。

首先我们回到AbstractApplicationContext.refresh()方法,找到代码:invokeBeanFactoryPostProcessors(beanFactory),单击该行代码跳转到具体的实现。

  1. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  2. // 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
  3. // 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
  4. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  5. // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
  6. // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
  7. if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  8. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  9. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  10. }
  11. }

1.拿到当前应用上下文 beanFactoryPostProcessors 变量中的值,见代码块1详解。
2.实例化并调用所有已注册的 BeanFactoryPostProcessor,见代码块2详解。

二、getBeanFactoryPostProcessors

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

这边 getBeanFactoryPostProcessors()会拿到当前应用上下文中已经注册的BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors 是返回空的。

如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量中了?
该成员变量的值是哪里设置的呢?查找后发现,来自AbstractApplicationContext.addBeanFactoryPostProcessor()方法被调用的时候设置的。

  1. @Override
  2. public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
  3. Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
  4. this.beanFactoryPostProcessors.add(postProcessor);
  5. }

AbstractApplicationContext.addBeanFactoryPostProcessor()方法是留给业务扩展时调用的,例如在springboot初始化时,ConfigurationWarningsApplicationContextInitializer类的initialize方法中就有调用:

  1. @Override
  2. public void initialize(ConfigurableApplicationContext context) {
  3. context.addBeanFactoryPostProcessor(
  4. new ConfigurationWarningsPostProcessor(getChecks()));
  5. }

三、invokeBeanFactoryPostProcessors

  • invokeBeanFactoryPostProcessors方法是:调用beanFactory的后置处理器,后面s表示复数,该方法两个参数:beanFactory一个单对象,和beanFactoryPostProcessors1个beanFactory后置处理器列表。
  • bean后置处理器处理的是bean实例
  • beanfactory后置处理器处理的是bean的定义,就是尚未实例化的bean
  1. public static void invokeBeanFactoryPostProcessors(
  2. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3. // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  4. Set<String> processedBeans = new HashSet<String>();
  5. // 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
  6. // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
  7. if (beanFactory instanceof BeanDefinitionRegistry) {
  8. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  9. // 用于存放普通的BeanFactoryPostProcessor
  10. List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
  11. // 用于存放BeanDefinitionRegistryPostProcessor
  12. List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
  13. // 2.首先处理入参中的beanFactoryPostProcessors
  14. // 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
  15. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  16. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  17. // 2.1 如果是BeanDefinitionRegistryPostProcessor
  18. BeanDefinitionRegistryPostProcessor registryProcessor =
  19. (BeanDefinitionRegistryPostProcessor) postProcessor;
  20. // 2.1.1 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
  21. registryProcessor.postProcessBeanDefinitionRegistry(registry);
  22. // 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
  23. registryProcessors.add(registryProcessor);
  24. } else {
  25. // 2.2 否则,只是普通的BeanFactoryPostProcessor
  26. // 2.2.1 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
  27. regularPostProcessors.add(postProcessor);
  28. }
  29. }
  30. // Do not initialize FactoryBeans here: We need to leave all regular beans
  31. // uninitialized to let the bean factory post-processors apply to them!
  32. // Separate between BeanDefinitionRegistryPostProcessors that implement
  33. // PriorityOrdered, Ordered, and the rest.
  34. // =====================================================================
  35. // 这后面的代码都是执行的是第一个参数beanFactory的获取到的BeanFactoryPostProcessor
  36. // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
  37. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
  38. // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
  39. // 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
  40. // 3.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
  41. String[] postProcessorNames =
  42. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  43. // 3.2 遍历postProcessorNames
  44. for (String ppName : postProcessorNames) {
  45. // 3.3 校验是否实现了PriorityOrdered接口
  46. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  47. // 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中,
  48. // beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
  49. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  50. // 3.5 将要被执行的加入processedBeans,避免后续重复执行
  51. processedBeans.add(ppName);
  52. }
  53. }
  54. // 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
  55. sortPostProcessors(currentRegistryProcessors, beanFactory);
  56. // 3.7 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
  57. // 因为实现了BeanDefinitionRegistryPostProcessor接口的类,会执行两个方法,
  58. // 第一个方法是:postProcessBeanDefinitionRegistry方法
  59. // 第二个方法是:postProcessBeanFactory方法,这个方法放在后面执行
  60. registryProcessors.addAll(currentRegistryProcessors);
  61. // 3.8 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
  62. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  63. // 3.9 执行完毕后, 清空currentRegistryProcessors
  64. currentRegistryProcessors.clear();
  65. // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
  66. // 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
  67. // 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
  68. // 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
  69. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  70. for (String ppName : postProcessorNames) {
  71. // 校验是否实现了Ordered接口,并且还未执行过
  72. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  73. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  74. processedBeans.add(ppName);
  75. }
  76. }
  77. sortPostProcessors(currentRegistryProcessors, beanFactory);
  78. registryProcessors.addAll(currentRegistryProcessors);
  79. // 4.2 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
  80. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  81. currentRegistryProcessors.clear();

1.判断beanFactory是否为 BeanDefinitionRegistrybeanFactory是在之前的 obtainFreshBeanFactory方法获取的,obtainFreshBeanFactory方法如果这里是基于注解的情况下,是在初始化的时候就已经是构建好的,初始化的时候构建的是DefaultListableBeanFactory。而 DefaultListableBeanFactory 实现了BeanDefinitionRegistry 接口,因此beanFactory instanceof BeanDefinitionRegistry 结果为 true

3.4 获取ppName 对应的 bean 实例,添加到 currentRegistryProcessors 中,准备执行。beanFactory.getBean 方法会触发创建 ppName 对应的 bean 实例对象,创建 bean 实例是 IoC 的另一个核心内容,之后会单独解析,目前暂不深入解析。

优秀的博主:https://www.zhihu.com/people/opiece.me/posts

四、基本使用

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

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