Spring BeanFactoryPostProcessor 和 BeanPostProcessor有什么用?
BeanFactoryPostProcessor
和 BeanPostProcessor
都是 Spring 框架中非常重要的扩展点,我们在开发中可以利用 Spring 容器实例化 Bean、配置 Bean 以及初始化 Bean 的过程中进行自定义的干预。但它们的作用时机和作用对象不同。
1. BeanFactoryPostProcessor
:
-
作用时机: 在 Spring 容器实例化Bean 之前 调用。更准确地说,是在 Spring 容器读取 Bean 定义信息之后, 在 Bean 实例化之前。
-
作用对象:
BeanFactory
本身以及 Bean 定义 (BeanDefinition
)。 -
主要用途:
- 修改 Bean 定义: 可以修改
BeanDefinition
的属性,例如:- 修改 Bean 的类名
- 修改 Bean 的作用域 (scope)
- 修改 Bean 的属性值
- 添加或删除 Bean 的依赖关系
- 修改 Bean 的初始化方法和销毁方法
- 修改 Bean 的自动装配模式
- 等等
- 添加自定义的属性编辑器 (PropertyEditor): 可以注册自定义的
PropertyEditor
,用于将字符串类型的配置值转换为 Bean 属性所需的类型。 - 读取外部配置: 可以读取外部配置文件(例如,properties 文件、YAML 文件、数据库等),并根据配置信息修改 Bean 定义。
- 修改 Bean 定义: 可以修改
-
关键方法:
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
: 这是BeanFactoryPostProcessor
接口中唯一的方法,它接收一个ConfigurableListableBeanFactory
对象作为参数,允许你对BeanFactory
进行修改。
-
常用实现类:
-
PropertyPlaceholderConfigurer
: 用于属性占位符替换,可以将配置文件中的占位符(例如,${jdbc.url}
)替换为实际的值。<!-- Spring 2.5 及之前 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations" value="classpath:database.properties"/> </bean><!-- Spring 3.1 之后, 推荐使用 context 命名空间 --> <context:property-placeholder location="classpath:database.properties"/>
-
PropertySourcesPlaceholderConfigurer
: Spring 3.1 引入,是PropertyPlaceholderConfigurer
的增强版,可以从多个属性源(例如,环境变量、系统属性、配置文件等)中解析占位符。 -
CustomScopeConfigurer
: 用于自定义作用域 (scope)。<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="myScope" value="com.example.MyScope"/></map></property> </bean>
-
CustomEditorConfigurer
: 用于注册自定义的属性编辑器。
-
-
BeanDefinitionRegistryPostProcessor
- 是
BeanFactoryPostProcessor
的子接口. - 可以在 Bean 定义加载完成后,但在 Bean 实例化之前执行,允许添加、删除或修改 Bean 定义。
- Spring 内置实现:
ConfigurationClassPostProcessor
(处理@Configuration
注解的配置类).
- 是
-
执行顺序: 如果有多个
BeanFactoryPostProcessor
,Spring 会根据它们的顺序(PriorityOrdered
、Ordered
或无序)依次调用。BeanDefinitionRegistryPostProcessor
会先于普通的BeanFactoryPostProcessor
执行.
2. BeanPostProcessor
:
-
作用时机: 在 Bean 实例化、属性填充 之后,但在 Bean 初始化方法(
@PostConstruct
、InitializingBean.afterPropertiesSet
、init-method
)执行 前后 调用。 -
作用对象: Bean 实例。
-
主要用途:
- 修改 Bean 实例: 可以修改 Bean 的属性值,或者返回一个完全不同的 Bean 实例(例如,代理对象)。
- 执行自定义的初始化逻辑: 可以在 Bean 初始化之前或之后执行一些自定义的逻辑。
- AOP (面向切面编程): Spring AOP 就是通过
BeanPostProcessor
来实现的。AbstractAutoProxyCreator
就是一个BeanPostProcessor
,它会在 Bean 初始化后创建代理对象。 - 处理注解: 例如处理
@Autowired
,@Value
,@Resource
等注解。
-
关键方法:
postProcessBeforeInitialization(Object bean, String beanName)
: 在 Bean 初始化 之前 调用。postProcessAfterInitialization(Object bean, String beanName)
: 在 Bean 初始化 之后 调用。- 这两个方法都接收两个参数:
bean
: 当前的 Bean 实例。beanName
: Bean 的名称。
- 这两个方法都可以返回修改后的 Bean 实例,或者返回原始的 Bean 实例。
-
常用实现类:
AutowiredAnnotationBeanPostProcessor
: 处理@Autowired
、@Value
、@Inject
等注解,实现依赖注入。CommonAnnotationBeanPostProcessor
: 处理一些通用的 JSR-250 注解,例如@PostConstruct
、@PreDestroy
、@Resource
。RequiredAnnotationBeanPostProcessor
: 检查带有@Required
注解的属性是否已设置(已过时)。AbstractAutoProxyCreator
: Spring AOP 的核心组件,用于创建代理对象。
-
执行顺序: 如果有多个
BeanPostProcessor
,Spring 会根据它们的顺序(PriorityOrdered
、Ordered
或无序)依次调用。 -
InstantiationAwareBeanPostProcessor
:BeanPostProcessor
的子接口,在 Bean 实例化 前后 执行。- 可以控制 Bean 的实例化过程,例如返回一个代理对象而不是原始的 Bean 实例。
- 包含
postProcessBeforeInstantiation
和postProcessAfterInstantiation
方法.
区别总结:
特性 | BeanFactoryPostProcessor | BeanPostProcessor |
---|---|---|
作用时机 | Bean 实例化 之前 | Bean 实例化、属性填充 之后,初始化方法 前后 |
作用对象 | BeanFactory 和 BeanDefinition | Bean 实例 |
主要用途 | 修改 Bean 定义、添加自定义属性编辑器、读取外部配置 | 修改 Bean 实例、执行自定义初始化逻辑、AOP |
关键方法 | postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) | postProcessBeforeInitialization(Object bean, String beanName) postProcessAfterInitialization(Object bean, String beanName) |
执行顺序 | 根据 PriorityOrdered 、Ordered 或无序依次执行。BeanDefinitionRegistryPostProcessor 会先于普通的 BeanFactoryPostProcessor 执行. | 根据 PriorityOrdered 、Ordered 或无序依次执行 |
对容器的影响 | 可以修改容器的配置 | 不能修改容器的配置,只能修改 Bean 实例 |
对 Bean 的影响 | 影响所有 Bean 的创建过程 | 可以针对特定 Bean 或所有 Bean 进行处理 |
示例:
// BeanFactoryPostProcessor 示例 (修改 Bean 定义)
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myBean");beanDefinition.setScope("prototype"); // 将 myBean 的作用域修改为 prototype}
}//BeanPostProcessor (修改Bean实例)
public class MyBeanPostProcessor implements BeanPostProcessor{@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if(bean instanceof MyBean){((MyBean) bean).setName("Modified Name"); //修改属性}return bean;}
}
总结:
BeanFactoryPostProcessor
和 BeanPostProcessor
是 Spring 框架中两个非常重要的扩展点,它允许我们在开发过程中对 Bean 生命周期的不同阶段进行自定义的干预。 BeanFactoryPostProcessor
主要用于修改 Bean 定义,而 BeanPostProcessor
主要用于修改 Bean 实例或执行自定义的初始化逻辑。
相关文章:
Spring BeanFactoryPostProcessor 和 BeanPostProcessor有什么用?
BeanFactoryPostProcessor 和 BeanPostProcessor 都是 Spring 框架中非常重要的扩展点,我们在开发中可以利用 Spring 容器实例化 Bean、配置 Bean 以及初始化 Bean 的过程中进行自定义的干预。但它们的作用时机和作用对象不同。 1. BeanFactoryPostProcessor: 作用…...
Centos7 Gitlab17部署
确保你的安装源正常 1.安装依赖项 sudo yum install -y curl policycoreutils-python openssh-server openssh-clients postfix 2.安装Gitlab (1)添加仓库 curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh | sudo bash (2) 安装Gitl…...
一文解读DeepSeek在工业制造领域的应用
引言 在当今数字化浪潮席卷全球的背景下,各个行业都在积极寻求创新与变革,工业制造领域也不例外。然而,传统工业制造在生产效率、质量控制、成本管理等方面面临着诸多挑战。在这一关键时期,人工智能技术的兴起为工业制造带来了新的…...
基于动态 FOF(基金中的基金)策略的基金交易推荐系统的设计与实现思路
下面为你呈现一个基于动态 FOF(基金中的基金)策略的基金交易推荐系统的设计与实现思路,同时给出一个简单的 Python 示例代码。 系统设计 1. 需求分析 收集各类基金的历史数据,涵盖净值、收益率、风险指标等。依据动态 FOF 策略…...
第一次程序Hello Python
Python环境安装 安装地址 安装地址 https://www.python.org/ 1. 安装Python 下载完成后,双击安装包(如python-3.13.2.exe),按照提示进行安装。在安装过程中,确保勾选“Add Python to PATH”选项,以便在命…...
nvm 切换node 版本 但是没有带星号*
在 Windows 系统中配置 NVM_SYMLINK 环境变量的步骤如下: 1️⃣ 设置变量路径 变量名:NVM_SYMLINK 变量值:建议设置为 C:\Program Files\nodejs(需与后续步骤中 NVM 配置的符号链接路径一致) 2️⃣ 配置系统环境变量…...
Java定时任务的三重境界:从单机心跳到分布式协调
《Java定时任务的三重境界:从单机心跳到分布式协调》 本文将以生产级代码标准,揭秘Java定时任务从基础API到分布式调度的6种实现范式,深入剖析ScheduledThreadPoolExecutor与Quartz Scheduler的线程模型差异,并给出各方案的性能压…...
1.NextJS基础
NextJS注意要点 文件用来定义路由,folder name becomes the route name注意区分客户端渲染和服务器渲染 html渲染完成后给到客户端(此时网页内容已经全部提供),有利于crawler和优化seo逻辑更简单request deduplication减少API请求…...
晶晨/全志/联发科芯片系列电视盒子改固件包教程
声明:对电视盒子进行改包(修改固件包)是一项有一定技术门槛且存在风险的操作,可能会导致盒子变砖、失去保修等问题,同时私自修改固件可能违反相关法律法规和使用协议。以下为你提供一个通用的大致改包教程,…...
2025最新3个wordpress好用的主题
红色大气的wordpress企业主题,适合服务行业的公司搭建企业官方网站使用。是一款专为中小企业和个人开发者设计的WordPress主题,旨在提供专业的网站构建解决方案。 通过此WordPress主题,用户可以轻松创建和维护一个专业的企业网站,…...
GZCTF平台搭建及题目上传
前言 我用手里的Ubuntu虚拟机搭建的,大家根据自己的实际情况来吧 安装及部署 首先,你的虚拟机需要有Docker和Docker-Compose,前者可以看我之前的文章,另外一个可以输入下面的命令安装,注意先获取管理员权限ÿ…...
openGauss关联列数据类型不一致引起谓词传递失败
今天分享一个比较有意思的案例 注意:因为原始SQL很长,为了方便排版,简化了SQL 下面SQL跑60秒才出结果,客户请求优化 select dtcs.owner, dtcs.table_name, dtcs.column_name, dct.commentsfrom dba_tab_columns dtcsleft outer j…...
【网络安全基础学习】渗透测试工具--Burp Suite详细教程
Burp Suite与SniffMaster:网络安全工具的双剑合璧 Burp Suite(简称BP)是一款用于攻击web应用程序的集成平台。它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程。然而,除了Burp…...
手机测试,工作中学习
要学习各种机型的截图方式、开发模式在哪。 荣耀机型:截图:关节快速敲两下。开发者模式在“系统和更新”里。 1.出现缺陷,需要获取日志。 学习adb生成日志:当测试中出现缺陷的,使用adb logcat -d > d:/log.txt …...
ctfshow WEB web2
1.查当前数据库名称 or 11 union select 1,database(),3 limit 1,2;#-- 得到数据库名称web2 2.查看数据库表的数量 or 11 union select 1,(select count(*) from information_schema.tables where table_schema web2),3 limit 1,2;#-- 得到数据库表数量为2 3.查表的名字 第…...
大疆上云api介绍
概述 目前对于 DJI 无人机接入第三方云平台,主要是基于 MSDK 开发定制 App,然后自己定义私有上云通信协议连接到云平台中。这样对于核心业务是开发云平台,无人机只是其中一个接入硬件设备的开发者来说,重新基于 MSDK 开发 App 工作量大、成本高,同时还需要花很多精力在无人…...
ASP.NET Web API + VUE3 整合阿里云OSS,后端API生成预签名上传Url,前端VUE进行上传
1、后端API 我用的是.net sdk6,所以先安装了这个Aliyun.OSS.SDK.NetCore 下面是后端生成上传Url的参考代码,主意request.ContentType,如果这里要是设置了,那么前端也要设置成一样的,如果前端是获取文件的contentType&…...
Java基础 3.22
1.break练习 //1-100之内的数求和,求当和第一次大于20的当前数i public class Break01 {public static void main(String[] args) {int n 0;int count 0;for (int i 1; i < 100; i) {count i;System.out.println("当前和为" count);if (count &g…...
如何快速解决 Postman 报错?
介绍一些 Postman 常见的报错与处理方法,希望能够对大家有所帮助。 Postman 一直转圈打不开的问题 Postman 报错处理指南:常见报错与解决方法...
软件性能效率测试工具有哪些?专业第三方软件检测机构推荐
在软件开发的新时代,软件性能效率测试已经成为每个企业不可或缺的一部分。无论是在竞争激烈的市场中,还是在追求卓越用户体验的过程中,都需要进行有效的性能测试。 一、软件性能效率测试的目标 1、响应时间:确保用户请求的响…...
手机销售终端MPR+LTC项目项目总体方案P183(183页PPT)(文末有下载方式)
资料解读:手机销售终端 MPRLTC 项目项目总体方案 详细资料请看本解读文章的最后内容。在当今竞争激烈的市场环境下,企业的销售模式和流程对于其发展起着至关重要的作用。华为终端正处于销售模式转型的关键时期,波士顿 - 华为销售终端 MPRLTC …...
redis使用
redis集群搭建可参考:redis集群搭建-CSDN博客 一、简述 Redis(Remote Dictionary Server)是一个开源的、基于内存的高性能键值对存储系统,通常用作数据库、缓存和消息代理。它支持多种数据结构,包括字符串、哈希、列…...
深入 SVG:矢量图形、滤镜与动态交互开发指南
1.SVG 详细介绍 SVG(Scalable Vector Graphics) 是一种基于 XML 的矢量图形格式,用于描述二维图形。 1. 命名空间 (Namespace) ★ 了解 命名空间 URI:http://www.w3.org/2000/svg 用途:在 XML 或 XHTML 中区分不同标…...
从双指针到单调栈,深挖“接雨水”的算法奥秘
从双指针到单调栈,深挖“接雨水”的算法奥秘 大家好,我是你们熟悉的算法领域大牛Echo_Wish。今天我们聊聊经典题目《接雨水》(Trapping Rain Water),不仅仅是讲解,而是深度对比两种高效解法:双…...
Labview和C#调用KNX API 相关东西
叙述:完全没有听说过KNX这个协议...................我这次项目中也是简单的用了一下没有过多的去研究 C#调用示例工程链接(labview调用示例在 DEBUG文件夹里面) 通过网盘分享的文件:KNX调用示例.zip 链接: https://pan.baidu.com/s/1NQUEYM11HID0M4ksetrTyg?pwd…...
Wireshark网络抓包分析使用详解
序言 之前学计网还有前几天备考华为 ICT 网络赛道时都有了解认识 Wireshark,但一直没怎么专门去用过,也没去系统学习过,就想趁着备考的网络相关知识还没忘光,先来系统学下整理点笔记~ 什么是抓包?抓包就是将网络传输…...
linux命令行工具进阶
文章目录 前言ssh免密登录,免密码登录,公私钥查看与修改IP地址临时修改永久修改 mount临时切换根文件系统永久切换根文件系统loop文件partedinitramfsuboot command line 前言 本文记录了一些不经常用到,但在某个时刻需要用到的一些指令。 免…...
【Linux文件IO】Linux中标准IO的API的描述和基本用法
Linux中标准IO的API的描述和基本用法 一、标准IO相关API1、文件的打开和关闭示例代码: 2、文件的读写示例代码:用标准IO(fread、fwrite)实现文件拷贝(任何文件均可拷贝) 3、文件偏移设置示例代码: 4、fgets fputs fget…...
【netstat和ss】Windows和Linux下的,网络连接排查简单案例
网络连接排查利器:netstat与ss命令详解 初识netstat:Windows下的网络连接查看工具 需要查看本机的网络连接情况时,Windows系统提供了一个非常实用的命令:netstat。和findstr组合形成一个有用的组合命令: netstat -a…...
【WPF】MVVM模式实现数据绑定以及Command事件绑定
1.引用类 using System.ComponentModel2.创建Command自定义类 public class DelegateCommand : ICommand{public bool CanExecute(object parameter){if (CanExecuteFunc null)return true;return this.CanExecuteFunc(parameter);}public event EventHandler CanExecuteChan…...
Flutter快速搭建聊天
之前项目中使用的环信聊天,我们的App使用的Flutter开发的 。 所以,就使用的 em_chat_uikit ,这个是环信开发的Flutter版本的聊天。 一开始,我们也用的环信的聊天,是收费的,但是,后面就发现&…...
网络层之IP协议
在讨论传输层时, 我们都只讨论了发送方和接收方的问题, 而没有讨论中间的网络形态的问题. 也就是数据包如何从主机传送到主机的? 如图, 主机B发送数据到主机C, 发送报文需要进行路径选择, 主机B-> F-> G-> H-> C-> D -> 主机C 这条路径是如何被选择出来的?…...
【设计模式】策略模式(Strategy Pattern)详解
策略模式(Strategy Pattern)详解 一、策略模式的定义 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一组算法,将每个算法封装起来,并使它们可以相互替换,从而让算法的…...
Elasticsearch:构建 AI 驱动的搜索体验
Elasticsearch 介绍 当你开始使用 Elastic 时,你将使用 Elasticsearch Relevance Engine™(ESRE),它专为 AI 搜索应用程序提供支持。借助 ESRE,你可以利用一整套开发者工具,包括 Elastic 的文本搜索、向量…...
数据文件误删除,OceanBase中如何重建受影响的节点
当不慎误删数据文件且当前没有现成的可替换节点时,在OceanBase中,不必急于采取极端措施,可以考虑运用 server_permanent_offline_time 参数,来重建受影响的节点。 原理: server_permanent_offline_time 是 OceanBase数…...
MySQL面试专题
1.什么是BufferPool? Buffer Pool基本概念 Buffer Pool:缓冲池,简称BP。其作用是用来缓存表数据与索引数据,减少磁盘IO操作,提升效率。 Buffer Pool由缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制…...
Redmi Note 11 T pro + 刷入 LinegaOs 22.1 记录 手机已经解锁bl.
Redmi Note 11 T pro 刷入 LinegaOs 22.1 记录 手机已经解锁bl. 获取LIneagaOS源码, 以及https://github.com/xiaomi-mediatek-devs 这个组织提供的代码,非常感谢 环境要求: ubuntu 22.04 需要准备的依赖 sudo apt install git curl vim…...
Python+Requests+Pytest+YAML+Allure接口自动化框架
GitHub源码地址(详细注释):源码 调试项目python自主搭建:附项目源码 一、项目介绍 本项目是基于 PythonRequestsPytestYAMLAllure 搭建的 接口自动化测试框架,用于对 REST API 进行测试。 框架的主要特点包括&#…...
如何解决Redis缓存异常问题(雪崩、击穿、穿透)
引言 Redis作为一种高性能的内存数据库,被广泛应用于缓存系统的构建中。然而,在实际应用过程中,我们常常会遇到三种典型的缓存异常问题:缓存雪崩、缓存击穿和缓存穿透。这些问题如果处理不当,可能会导致系统性能下降&…...
如何使用 Postman 进行接口测试?
使用 Postman 这一工具,可以轻松地进行接口测试。以下是一份简单的使用教程,帮助你快速上手。 Postman 接口测试教程:详细步骤及操作技巧...
记一次线上环境JAR冲突导致程序报错org.springframework.web.util.NestedServletException
一、问题描述 有个文件导入功能,用到了Hutool 的加密解密功能,本地运行完全可以,但是线上报错:“org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFou…...
VLAN实验
一:实验拓扑 二:实验需求 1、PC1和PC3所在接口为access接口,属于VLAN 2 2、PC2/4/5/6处于同一网段 其中PC2可以访问PC4/5/6 PC4可以访问PC5不能访问PC6 PC5不能访问PC6 3、PC1/3和PC2/4/5/6不在一个网段,且可以正常通讯 4、…...
FPGA中串行执行方式之状态机
FPGA中串行执行方式之状态机 在FPGA中,默认情况下,逻辑是并行执行的,因为FPGA的硬件资源是并行的。然而,在某些情况下,你可能需要某一段逻辑以串行方式执行。这可以通过以下几种方法实现:使用状态机(Finite State Machine, FSM)、使用计数器控制、使用流水线(Pipel…...
【常用的中间件】
中间件(Middleware)是位于客户端和服务器之间的软件层,用于处理客户端请求和服务器响应之间的各种任务。中间件可以提供多种功能,如负载均衡、消息队列、缓存、身份验证等。以下是常用的中间件及其作用: 1. 消息队列中…...
spring - 十二种事务失效场景
目录 编辑 一、方法内部调用 1、原理: 2、结论: 3、解决方法: 1. 增加一个service,把一个事务的方法移到新增加的service方法里面,然后进行注入再调用 2. 在自己类中注入自己 3. 通过AopContentent 二、访问权限不是pubilc 三、方法用final修饰 四、没有被spr…...
python脚本处理excel文件
1.对比perl和python 分别尝试用perl和python处理excel文件,发现perl的比较复杂,比如说read excel就有很多方式 Spreadsheet::Read use Spreadsheet::ParseExcel 不同的method,对应的取sheet的cell方式也不一样。更复杂的是处理含有中文内…...
C#基础学习(二)C#数组生存手册:从入门到“血压拉满“的奇妙旅程
作为一只C#萌新,当你试图用数组装下整个世界时,系统可能会温柔地弹出一句**"Index was outside the bounds of the array."**。别慌!这份求生指南将用段子教你玩转数组 一、数组是什么 数组简单来说就是由相同元素组成的一个集合&a…...
MySQL 性能优化方向
MySQL 性能优化是一个系统性的工作,涉及数据库设计、查询优化、索引优化、硬件配置等多个方面。以下是 MySQL 性能优化的主要方向和具体优化方案: 一、数据库设计优化 1. 合理设计表结构 规范化设计:避免数据冗余,确保数据一致性。适度反规范化:在查询频繁的场景下,适当…...
2025年- G26-Lc100-57.插入间隔(max、min)--java版
1.题目描述 题目翻译: 给定一个不重叠的区间阵列 intervals,其中intervals[i] [starti, endi]表示第i一个区间的起始位置和结束位置,并且intervals 按照起始位置starti升序排序。 另外,给定一个新的区间newInterval [start, e…...
Burp Suite HTTPS解密原理
HTTPS HTTPS是在HTTP的基础上增加了SSL/TLS协议,提供了数据的加密、完整性校验和身份认证等安全保障。HTTPS的工作过程可以分为两个阶段:握手阶段和数据传输阶段。 流程如下图所示: 通过上面的图可以看到,在TCP建立连接后会发起…...