前言

BeanFactoryPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下

  1. public interface BeanFactoryPostProcessor {
  2. void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
  3. }

当你实现了这个接口的时候,可以对还没有初始化的bean的属性进行修改或添加

BeanFactoryPostProcessor注册

BeanPostProcessor的统一注册不同,BeanFactoryPostProcessor的注册是留给具体的业务实现的。它的维护是在AbstractApplicationContext类中

  1. private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors =
  2. new ArrayList<>();
  3. public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
  4. Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
  5. this.beanFactoryPostProcessors.add(postProcessor);
  6. }

执行原理

调用逻辑在AbstractApplicationContext.invokeBeanFactoryPostProcessors方法中

这个方法比较长,可以重点关注我添加注释的地方


  1. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  2. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  3. if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  4. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  5. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  6. }
  7. }
  8. public static void invokeBeanFactoryPostProcessors(
  9. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  10. Set<String> processedBeans = new HashSet<String>();
  11. // 1.判断beanFactory是否为BeanDefinitionRegistry,在这里普通的beanFactory是DefaultListableBeanFactory,而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
  12. if (beanFactory instanceof BeanDefinitionRegistry) {
  13. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  14. List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
  15. List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
  16. // 2.处理入参beanFactoryPostProcessors
  17. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  18. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  19. BeanDefinitionRegistryPostProcessor registryProcessor =
  20. (BeanDefinitionRegistryPostProcessor) postProcessor;
  21. // 如果是BeanDefinitionRegistryPostProcessor则直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
  22. registryProcessor.postProcessBeanDefinitionRegistry(registry);
  23. registryProcessors.add(registryProcessor);
  24. } else {
  25. regularPostProcessors.add(postProcessor);
  26. }
  27. }
  28. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
  29. // 3找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
  30. String[] postProcessorNames =
  31. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  32. for (String ppName : postProcessorNames) {
  33. // 校验是否实现了PriorityOrdered接口
  34. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  35. // 获取对应的bean实例, 添加到currentRegistryProcessors中,
  36. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  37. processedBeans.add(ppName);
  38. }
  39. }
  40. // 排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
  41. sortPostProcessors(currentRegistryProcessors, beanFactory);
  42. registryProcessors.addAll(currentRegistryProcessors);
  43. // 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
  44. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  45. // 清空currentRegistryProcessors
  46. currentRegistryProcessors.clear();
  47. // 4.与上边3的流程差不多,这是这里处理的是实现Ordered接口
  48. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  49. for (String ppName : postProcessorNames) {
  50. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  51. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  52. processedBeans.add(ppName);
  53. }
  54. }
  55. sortPostProcessors(currentRegistryProcessors, beanFactory);
  56. registryProcessors.addAll(currentRegistryProcessors);
  57. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  58. currentRegistryProcessors.clear();
  59. // 5.调用所有剩下的BeanDefinitionRegistryPostProcessors
  60. boolean reiterate = true;
  61. while (reiterate) {
  62. reiterate = false;
  63. // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
  64. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  65. for (String ppName : postProcessorNames) {
  66. // 跳过已经执行过的
  67. if (!processedBeans.contains(ppName)) {
  68. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  69. processedBeans.add(ppName);
  70. reiterate = true;
  71. }
  72. }
  73. sortPostProcessors(currentRegistryProcessors, beanFactory);
  74. registryProcessors.addAll(currentRegistryProcessors);
  75. // 5遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
  76. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  77. currentRegistryProcessors.clear();
  78. }
  79. // 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
  80. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
  81. // 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
  82. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  83. } else {
  84. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  85. }
  86. // 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
  87. // 下面开始处理容器中的所有BeanFactoryPostProcessor
  88. // Do not initialize FactoryBeans here: We need to leave all regular beans
  89. // uninitialized to let the bean factory post-processors apply to them!
  90. // 8.找出所有实现BeanFactoryPostProcessor接口的类
  91. String[] postProcessorNames =
  92. beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  93. // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  94. // Ordered, and the rest.
  95. // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
  96. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  97. // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
  98. List<String> orderedPostProcessorNames = new ArrayList<String>();
  99. // 用于存放普通BeanFactoryPostProcessor的beanName
  100. List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  101. // 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
  102. for (String ppName : postProcessorNames) {
  103. // 8.2 跳过已经执行过的
  104. if (processedBeans.contains(ppName)) {
  105. // skip - already processed in first phase above
  106. } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  107. // 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
  108. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  109. } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  110. // 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
  111. orderedPostProcessorNames.add(ppName);
  112. } else {
  113. // 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
  114. nonOrderedPostProcessorNames.add(ppName);
  115. }
  116. }
  117. // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
  118. // 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
  119. // 9.1 对priorityOrderedPostProcessors排序
  120. sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  121. // 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
  122. invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  123. // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
  124. // 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
  125. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  126. for (String postProcessorName : orderedPostProcessorNames) {
  127. // 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
  128. orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  129. }
  130. // 10.2 对orderedPostProcessors排序
  131. sortPostProcessors(orderedPostProcessors, beanFactory);
  132. // 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
  133. invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  134. // Finally, invoke all other BeanFactoryPostProcessors.
  135. // 11.调用所有剩下的BeanFactoryPostProcessor
  136. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  137. for (String postProcessorName : nonOrderedPostProcessorNames) {
  138. // 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
  139. nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  140. }
  141. // 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
  142. invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  143. // Clear cached merged bean definitions since the post-processors might have
  144. // modified the original metadata, e.g. replacing placeholders in values...
  145. // 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
  146. // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
  147. beanFactory.clearMetadataCache();
  148. }

细心的同学可能会发现上方还出现了一个BeanDefinitionRegistryPostProcessor,这个东东其实是BeanFactoryPostProcessor的特殊实习,观察调用它的方法可以看到它需要一个参数:BeanDefinitionRegistry,通过这个参数可以更为方便的去做一些自定义bean的操作

总结一下上方的逻辑:

  1. BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor,分别放入两个集合
  2. 分别进行排序处理
  3. 按照优先级分别调用invokeBeanDefinitionRegistryPostProcessorsinvokeBeanFactoryPostProcessors方法
  4. 这两个invoke方法相信你可以想象的到无非就是循环调用这些实现类对应的方法

Spring的实现

查看这个接口的继承体系,可以看到这个接口的实现类是非常多的,各个实现类的功能如果感兴趣大家可以去慢慢挖掘一下

Spring扩展点之BeanFactoryPostProcessor的更多相关文章

  1. Spring扩展点之Aware接口族

    引言 Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContex ...

  2. Spring扩展点-v5.3.9

    Spring 扩展点 **本人博客网站 **IT小神 www.itxiaoshen.com 官网地址****:https://spring.io/projects/spring-framework T ...

  3. Spring扩展点之BeanPostProcessor

    前言 BeanPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下 public interface BeanPostProcessor { Object postPro ...

  4. Spring扩展点之FactoryBean接口

    前言 首先看一下接口定义 public interface FactoryBean<T> { /** * 返回对象实例 */ @Nullable T getObject() throws ...

  5. spring扩展点之PropertyPlaceholderConfigurer

    原理机制讲解 https://leokongwq.github.io/2016/12/28/spring-PropertyPlaceholderConfigurer.html 使用时多个配置讲解 ht ...

  6. Spring-IOC 扩展点 BeanFactoryPostProcessor及其子接口解析

    BeanFactoryPostProcessor 接口的英文描述: Allows for custom modification of an application context's bean de ...

  7. Spring中的扩展点

    Spring作为一个常用的IOC框架,在设计上预留了很多的扩展点,很多第三方开源框架,包括Spring自身也是基于这些扩展点实现的,这很好的体现了对修改关闭.对扩展开放的原则.总的来说Spring的扩 ...

  8. Spring源码系列 — BeanDefinition扩展点

    前言 前文介绍了Spring Bean的生命周期,也算是XML IOC系列的完结.但是Spring的博大精深,还有很多盲点需要摸索.整合前面的系列文章,从Resource到BeanDefinition ...

  9. Spring系列14:IoC容器的扩展点

    Spring系列14:IoC容器的扩展点 回顾 知识需要成体系地学习,本系列文章前后有关联,建议按照顺序阅读.上一篇我们详细介绍了Spring Bean的生命周期和丰富的扩展点,没有阅读的强烈建议先阅 ...

随机推荐

  1. Python:tarxjb简单、安全文件拷贝、传输

    tarxjb 简单.安全文件拷贝.传输 描述 通过python paramiko库实现简易ssh.sftp执行操作,从而实现文件的远程传输 Github 优点: 可靠传输,文件不易受损 安全传输,避免 ...

  2. python3 AES 加解密

    #coding:utf-8 import base64 from Crypto.Cipher import AES #注:python3 安装 Crypto 是 pip3 install -i htt ...

  3. html5 localStorage讲解

    早期的web中使用cookies在客户端保存诸如用户名等简单的信息,但是,在使用cookies存储永久数据存在以下问题. 1.cookies的大小限制在4kB,不适合大量的数据存储. 2.浏览器还限制 ...

  4. XSS-Stored

    存储型XSS (持久性XSS) 将恶意JavaScript代码存储在数据库,当下次用户浏览的时候执行 Low <?php if( isset( $_POST[ 'btnSign' ] ) ) { ...

  5. Vi编辑网卡

    Vi /etc/sysconfig/network-scripts/ifcfg-ens33  1.光标定位到BOOTPROTO=后面 2.然后按x键进行删除 3.按i键打开编辑模式,输入BOOTPRO ...

  6. RST复位报文

    复位报文段: 一些特殊情况,TCP一端向另一端发送复位报文,以通知对方关闭链接或者重新建立链接. 产生复位报文的三种情况: 1. 当客户端访问一个不存在的端口时,目标主机会给客户端发送一个复位报文段. ...

  7. (转)LoadRunner集合点设置1

    集合点的意思时等到特定的用户数后再一起执行某个操作,比如一起保存,一起提交(我们通常意义上的并发数并不是指一起提交或者一起保存),一般情况下使用不到集合点,不过,订票系统或者促销类需要用到,比如说某个 ...

  8. GIT : IDEA切换到某个tag

    背景看一本presto的书,发现版本用的是presto-0.107这个版本.然后我去Apache clone下源码,发现分支只有几个,但是下载页面却有很多不同的版本 然后看Tag发现有很多. 然后我现 ...

  9. java 深入理解jvm内存模型 jvm学习笔记

    jvm内存模型 这是java堆和方法区内存模型 参考:https://www.cnblogs.com/honey01/p/9475726.html Java 中的堆也是 GC 收集垃圾的主要区域.GC ...

  10. 清北学堂(2019 5 3) part 6

    今天讲STL 1.pair——<algorithm> 声明形如pair<int,int> x;(不是int也可以),表示x有前后两个成员,都是int类型,调用时写x.first ...