Spring扩展接口(3):BeanFactoryPostProcessor
在此系列文章中,我总结了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的更多相关文章
- Spring拓展接口之BeanFactoryPostProcessor,占位符与敏感信息解密原理
前言 开心一刻 一只被二哈带偏了的柴犬,我只想弄死隔壁的二哈 what:是什么 BeanFactoryPostProcessor接口很简单,只包含一个方法 /** * 通过BeanFactoryPos ...
- Spring8:一些常用的Spring Bean扩展接口
前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...
- 0001 - Spring 框架和 Tomcat 容器扩展接口揭秘
前言 在 Spring 框架中,每个应用程序上下文(ApplicationContext)管理着一个 BeanFactory,BeanFactory 主要负责 Bean 定义的保存.Bean 的创建. ...
- 深入理解Spring系列之八:常用的扩展接口
转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...
- spring扩展点之一:BeanFactoryPostProcessor和BeanPostProcessor
一.BeanFactoryPostProcessor和BeanPostProcessor的区别 BeanFactoryPostProcessor和BeanPostProcessor都是spring初始 ...
- spring初始化源码浅析之关键类和扩展接口
目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...
- Spring的BeanPostProcessor和BeanFactoryPostProcessor区别
Spring提供了两种后处理bean的扩展接口,分别为BeanPostProcessor和BeanFactoryPostProcessor,这两者在使用上是有所区别的. BeanPostProcess ...
- spring扩展点整理
本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...
- spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别
主要区别就是: BeanFactoryPostProcessor可以修改BEAN的配置信息而BeanPostProcessor不能,下面举个例子说明 BEAN类: package com.spring ...
- Spring常用接口和类
一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...
随机推荐
- 【NestJS系列】从Nest CLI开始入门
初识Nest JS Nest 是一个渐进的 Node.js 框架,它可以在 TypeScript 和 JavaScript (ES6.ES7.ES8)之上构建高效.可伸缩的企业级服务器端应用程序. N ...
- 如何在 Windows Server 2022 阿里云服务器上搭建自己的 MQTT 服务器。
一.简介 最近,在做一个项目的时候,需要在线管理网络继电器,以前也做过硬件的项目,但是这样的项目不多.现在我想实现一个在线可以接受网络继电器发送的信号,也可以向网络继电器发送命令,控制其的运行.这个功 ...
- 即构 SDK 6月迭代:新增拉流画面镜像等功能,为开发者提供更大便利
即构SDK6月新版本已上线,本月SDK迭代主要新增了拉流画面镜像功能,媒体播放器新增支持缓存相关的设置,新增支持设置对焦模式和曝光模式等功能,多个功能模块的灵活设置,让开发者能更便利的自定义选择,为用 ...
- 一张表实现类某音的视频"评论回复"功能
前言 现如今,不管是哪种类型的应用,评论区都少不了.从工具类的到媒体信息流类的,评论留言都是最基本的互动环节.比如抖音短视频下,针对视频每个用户都可以发表自己的观点:而针对用户的评论,其他的用户又可 ...
- Go 语言的 nil 能比较自己吗
nil 是什么? 可以看看官方的描述,在 buildin/buildin.go 里: // nil is a predeclared identifier representing the zero ...
- Centos7中Oracle占用CPU过高(解决方案)
Centos7中Oracle占用CPU过高(解决方案) 前言: 99%的问题几乎都是SQL的问题,一般SQL可能会出现以下几种情况: 相关SQL搜索条件没有加索引 索引失效 联合查询过多 数据量过大 ...
- 一分钟学一个 Linux 命令 - rm
前言 大家好,我是 god23bin,欢迎回到咱们的<一分钟学一个 Linux 命令>系列,今天我要讲的是一个比较危险的命令,rm 命令,没错,你可以没听过 rm 命令,但是删库跑路你不可 ...
- 2023-7-26 Dynamic替代部分反射的简单实现方式
Dynamic与反射的使用 [作者]长生 实体类 public class School{ public int GetAge(){ return 100; } } 使用反射获取对象里的方法 Scho ...
- 关于selenium WebDriverException: Message: unknown error: DevToolsActivePort file doesnt exist 的解决方案
文章参考: https://hant-kb.kutu66.com/others/post_13460379 在浏览器设置参数时加入如下两行代码 1 # 取消沙盒模式 2 options.add_arg ...
- 抽象类 vs 接口【概念解析系列_2】【C# 基础】
〇.前言 抽象类和接口的相似之处还是很多的,但是它们的侧重点不同,本文将简单梳理下. 一.简介与示例 1.1 抽象类 抽象类就是不能使用 new 方法进行实例化的类,即没有具体实例对象的类. 抽象类有 ...