在此系列文章中,我总结了Spring几乎所有的扩展接口,以及各个扩展点的使用场景。并整理出一个bean在spring中从被加载到最终初始化的所有可扩展点的顺序调用图。这样,我们也可以看到bean是如何一步步加载到spring容器中的。


BeanFactoryPostProcessor

1、概述

public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

BeanFactoryPostProcessor是Spring框架中的一个重要接口,用于在BeanFactory加载Bean定义之后、实例化Bean之前对BeanFactory进行自定义修改和扩展。它允许开发人员在Spring容器加载配置文件并创建Bean实例之前对Bean定义进行操作,例如修改属性值、添加额外的元数据等。

在应用程序启动时,Spring容器会自动检测并调用所有实现了BeanFactoryPostProcessor接口的类的postProcessBeanFactory方法。开发人员可以利用这个方法来实现自定义的逻辑,从而实现一些高级的自定义逻辑和功能扩展。

前文介绍的BeanDefinitionRegistryPostProcessor为其子接口。

2、简单案例

下面是一个示例,展示了如何实现动态的给Bean修改属性值:

public class User {
String name;
String password;
} import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component; @Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
if (Objects.nonNull(beanDefinition)) {
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
propertyValues.addPropertyValue("name", "张三");
propertyValues.addPropertyValue("password", "123456");
}
}
}

同样,若当容器中有多个BeanFactoryPostProcessor的时候,可以通过实现PriorityOrdered或Ordered接口来指定顺序(优先执行PriorityOrdered的接口,其次是Ordered的接口,最后是没有实现任何排序的接口):

@Override
public int getOrder() {
return 0; //值越小,优先级越高
}

3、源码分析

  • 在MyBeanFactoryPostProcessor打上断点,启动SpringApplication,可以看到左下角的调用链路。

  • spring的AbstractApplicationContext的refresh方法,执行this.invokeBeanFactoryPostProcessors(beanFactory)。

  • 接下来进入核心的invokeBeanFactoryPostProcessors方法,大概逻辑是先取出所有实现了BeanFactoryPostProcessor接口的类,在for循环中根据实现类的优先级放入不同的ArrayList()等待调用,先PriorityOrdered,再Ordered,最后调用无优先级的实现类。
  • 注意:BeanDefinitionRegistryPostProcessor也实现了BeanFactoryPostProcessor接口,所以postProcessorNames也包含BeanDefinitionRegistryPostProcessor实现类,它已先于BeanFactoryPostProcessor执行,所以在for循环中需要排除,见if (!processedBeans.contains(ppName))。

  • 最后,遍历调用BeanFactoryPostProcessor的组件

Spring扩展接口(3):BeanFactoryPostProcessor的更多相关文章

  1. Spring拓展接口之BeanFactoryPostProcessor,占位符与敏感信息解密原理

    前言 开心一刻 一只被二哈带偏了的柴犬,我只想弄死隔壁的二哈 what:是什么 BeanFactoryPostProcessor接口很简单,只包含一个方法 /** * 通过BeanFactoryPos ...

  2. Spring8:一些常用的Spring Bean扩展接口

    前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...

  3. 0001 - Spring 框架和 Tomcat 容器扩展接口揭秘

    前言 在 Spring 框架中,每个应用程序上下文(ApplicationContext)管理着一个 BeanFactory,BeanFactory 主要负责 Bean 定义的保存.Bean 的创建. ...

  4. 深入理解Spring系列之八:常用的扩展接口

    转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...

  5. spring扩展点之一:BeanFactoryPostProcessor和BeanPostProcessor

    一.BeanFactoryPostProcessor和BeanPostProcessor的区别 BeanFactoryPostProcessor和BeanPostProcessor都是spring初始 ...

  6. spring初始化源码浅析之关键类和扩展接口

    目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...

  7. Spring的BeanPostProcessor和BeanFactoryPostProcessor区别

    Spring提供了两种后处理bean的扩展接口,分别为BeanPostProcessor和BeanFactoryPostProcessor,这两者在使用上是有所区别的. BeanPostProcess ...

  8. spring扩展点整理

    本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...

  9. spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别

    主要区别就是: BeanFactoryPostProcessor可以修改BEAN的配置信息而BeanPostProcessor不能,下面举个例子说明 BEAN类: package com.spring ...

  10. Spring常用接口和类

    一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...

随机推荐

  1. 曲线艺术编程 coding curves 第十四章 其它曲线(Miscellaneous Curves)

    第十四章 其它曲线(Miscellaneous Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ ...

  2. Git的基本操作(CUDR)及分支

    ## 安装 到Git官网下载,网站地址:https://git-scm.com/downloads 需要从网上下载一个,然后进行默认安装即可.安装完成后,在开始菜单里面找到 "Git --& ...

  3. 根据模板动态生成word(三)使用poi-tl生成word

    @ 目录 一.前言 1.什么是poi-tl 2.官方信息 2.1 源码仓库 2.2 中文文档 2.3 开源协议 3.poi-tl的优势 3.1 poi-tl和其他模板引擎的对比 3.2 poi-tl ...

  4. 图像处理_Retinex图像增强

    单尺度SSR (Single Scale Retinex) 图像 S ( x , y ) S(x,y) S(x,y)分解为两个不同的图像:反射图像 R ( x , y ) R(x,y) R(x,y), ...

  5. 2023年郑州轻工业大学校赛邀请赛mjh

    首先,很感谢老师的信任,选择我去参加此次比赛:其次,感谢wh,wyh两位队友的全程带飞.此次比赛是我第一次参加线下的比赛活动,内心难免激动与紧张. 比赛开始,队友直接找到了签到题进行解答,而我拿到了看 ...

  6. Solon v2.4.0 发布,Java 生态的新星燃起

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...

  7. 为什么Python是数据科学家的首选语言

    这篇文章全面探讨了Python作为数据科学领域首选语言的原因.从Python的历史.特性,到在数据科学中的应用实例,再到与其他数据科学语言的比较,以及在实际企业中的应用,我们深入剖析了Python的优 ...

  8. Shell 摘抄:growpart中的参数处理

    下面这段代码中,变量cur表示这次循环所要处理的参数.如果没有触发前面的选项开关,第一个参数会被赋值给$DISK,第二个参数会赋值给$PART. 强无敌!- while [ $# -ne 0 ]; d ...

  9. CMDB 相关

    CMDB 术语 CI(配置项) 配置管理解决方案(如CMDB)中的基本有形或无形实体. 为了交付IT服务而需要管理的任何组件. 通常包括IT服务.硬件.软件.架构.人员和正式文档(如流程文档和sla) ...

  10. Feign自定义重试策略及超时时间

    背景 feign可以配置重试策略及超时时间,但是无法根据业务场景动态的设置.可能会引起接口幂等,无效重试资源耗费,大数据量耗时操作报超时异常等问题.所以需要更细粒度的重试策略及超时时间配置. 自定义重 ...