Spring系列 BeanPostProcessor
文章目录
- BeanPostProcessor
- 注册时机
- 执行时机
- InstantiationAwareBeanPostProcessor
- SmartInstantiationAwareBeanPostProcessor
本文源码基于spring-beans-5.3.31
参考:https://docs.spring.io/spring-framework/reference/core/beans/factory-extension.html#beans-factory-extension-bpp
BeanPostProcessor 是 Spring 框架中的一个接口,用于在 bean 实例化和初始化过程中进行一些回调处理,可以对Bean进行一些扩展或修改。
BeanPostProcessor
注册时机
在AbstractApplicationContext#refresh
里进行注册。此时所有Bean的配置信息都已解析并加载完毕
注册时并未区分BeanPostProcessor具体是什么类型
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
AbstractBeanFactory维护了一个BeanPostProcessor列表,保存所有注册的 BeanPostProcessor
同时针对后期的使用提供了BeanPostProcessorCache这个类,用于缓存不同类型的BeanPostProcessor,从而进行不同的处理逻辑
通过懒加载策略进行初始化
BeanPostProcessorCache getBeanPostProcessorCache() {synchronized (this.beanPostProcessors) {BeanPostProcessorCache bppCache = this.beanPostProcessorCache;if (bppCache == null) {bppCache = new BeanPostProcessorCache();// 区分不同的实现类型,放到对应的list集合中for (BeanPostProcessor bpp : this.beanPostProcessors) {if (bpp instanceof InstantiationAwareBeanPostProcessor) {bppCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bpp);if (bpp instanceof SmartInstantiationAwareBeanPostProcessor) {bppCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bpp);}}if (bpp instanceof DestructionAwareBeanPostProcessor) {bppCache.destructionAware.add((DestructionAwareBeanPostProcessor) bpp);}if (bpp instanceof MergedBeanDefinitionPostProcessor) {bppCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bpp);}}this.beanPostProcessorCache = bppCache;}return bppCache;}
}
执行时机
BeanPostProcessor提供了Bean的生命周期的一些回调操作,所以它的执行是伴随着Bean的生命周期执行而执行的
InstantiationAwareBeanPostProcessor
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
扩展了 BeanPostProcessor,用于在 bean 实例化和初始化过程中进行更细粒度的处理。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {return null;}@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}
}
它提供了多个方法,下面是各个方法的作用
- postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
在 bean 实例化之前调用。可以用于检查 bean 的元数据,决定是否需要实例化该 bean,或者返回一个替代的实例。可以返回一个替代的 bean 实例,或者返回 null 继续正常的实例化流程。
- postProcessAfterInstantiation(Object bean, String beanName)
在 bean 实例化之后调用,可以用于逻辑处理,比如检查 bean 是否需要进行某些初始化操作。通常返回 true,表示允许继续进行属性填充。如果返回 false,则 Spring 将跳过属性的设置。
- postProcessProperties(PropertyValues pvs, Object bean, String beanName)
在填充 bean 属性之前调用,用于处理 PropertyValues。可以修改属性值或条件性地填充属性。
参数pvs 是待填充的属性值,bean 是当前的 bean 实例,beanName 是 bean 的名称。返回修改后的 PropertyValues,或者返回原始的 pvs。
4. postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
由于继承了BeanPostProcessor,所以postProcessBeforeInitialization(Object bean, String beanName)和postProcessAfterInitialization(Object bean, String beanName)这两个方法和BeanPostProcessor一致
SmartInstantiationAwareBeanPostProcessor
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {@Nullabledefault Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {return null;}@Nullabledefault Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)throws BeansException {return null;}default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {return bean;}
}
- Class<?> predictBeanType(Class<?> beanClass, String beanName)
- Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
- Object getEarlyBeanReference(Object bean, String beanName)
在 bean 实例化后、初始化之前调用,允许返回早期的 bean 引用。这可以解决循环依赖问题,特别是在需要提前获取 bean 的情况下。返回早期的 bean 实例,或原始的 bean(即不做任何更改)。
相关文章:

Spring系列 BeanPostProcessor
文章目录 BeanPostProcessor注册时机执行时机 InstantiationAwareBeanPostProcessorSmartInstantiationAwareBeanPostProcessor 本文源码基于spring-beans-5.3.31 参考:https://docs.spring.io/spring-framework/reference/core/beans/factory-extension.html#beans…...

Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)
0x01 漏洞概述 Qualitor 8.20及之前版本存在命令注入漏洞,远程攻击者可利用该漏洞通过PHP代码执行任意代码。 0x02 复现环境 FOFA:app"Qualitor-Web" 0x03 漏洞复现 PoC GET /html/ad/adpesquisasql/request/processVariavel.php?gridValoresPopHi…...

SpringBoot的概述与搭建
目录 一.SpringBoot的概述 二.SpringBoot 特点 三.SpringBoot 的核心功能 3.1起步依赖 3.2自动配置 四.SpringBoot 开发环境构建 五.SpringBoot 配置文件 六.SpringBoot数据访问管理 七.springboot注解 八.springboot集成mybatis 九.springboot全局异常捕获与处理 一…...

视频集成与融合项目中需要视频编码,但是分辨率不兼容怎么办?
在众多视频整合项目中,一个显著的趋势是融合多元化的视频资源,以实现统一监管与灵活调度。这一需求促使项目团队不断探索新的集成方案,确保不同来源的视频流能够无缝对接,共同服务于统一的调看与管理平台,进而提升整体…...

kafka 换盘重平衡副本 操作流程
一、起因 kakfa某块数据盘损坏,且数据无法恢复,需清空换新盘 二、梳理操作流程 查看topic信息 sh ./kafka-topics --bootstrap-server ***:9092 --list --exclude-internal 查看某个topic数据分布情况 sh ./kafka-topics --bootstrap-server ***:…...

vue3.0 + element plus 全局自定义指令:select滚动分页
需求:项目里面下拉框数据较多 ,一次性请求数据,体验差,效果就是滚动进行分页。 看到这个需求的时候,我第一反应就是封装成自定义指令,这样回头用的时候,直接调用就可以了。 第一步 第二步&…...

HarmonyOS/OpenHarmony 离线加载web资源,并实现web资源更新
关键词:h5离线包加载、h5离线包更新、沙箱 在上一篇文章中,我们已经介绍了如何将 rawfile 资源文件中的文件数据拷贝到沙箱下,那么该篇文章将介绍如何加载该沙箱目录下的文件资源(此处以打包后的web资源为例)…...

【Spark 实战】基于spark3.4.2+iceberg1.6.1搭建本地调试环境
基于spark3.4.2iceberg1.6.1搭建本地调试环境 文章目录 基于spark3.4.2iceberg1.6.1搭建本地调试环境环境准备使用maven构建sparksql编辑SparkSQL简单任务附录A iceberg术语参考 环境准备 IntelliJ IDEA 2024.1.2 (Ultimate Edition)JDK 1.8Spark 3.4.2Iceberg 1.6.1 使用mave…...
TCP连接建立中不携带数据的报文段为何不消耗序号解析
在TCP协议中,序号的使用是为了确保数据能够按照正确的顺序被接收端重组和确认。每个TCP报文段都有一个序号字段,用于标识该报文段中数据的起始位置相对于整个数据流的偏移量。 初始序号和三次握手 在TCP连接的建立过程中,三次握手是确保双方…...

JS设计模式之状态模式:优雅地管理应用中产生的不同状态
一. 前言 在过去,我们经常使用条件语句(if-else 语句)来处理应用程序中的不同状态。然而,这种方式往往会让代码变得冗长、难以维护,并可能引入潜在的 bug。而状态模式则提供了一种更加结构化和可扩展的方法来处理状态…...

C语言系列4——指针与数组(1)
我们开始C语言的指针与数组 这部分开始进阶了,得反复学习 在开始正题之前,写说一下我们都知道当写一个函数的时候需要进行传参,当实参传递给形参的时候,形参是有独立空间的,那么数组传参又是怎么样的呢,我…...
JS网页设计案例
下面是一个简单的 JavaScript 网页设计案例,展示了如何使用 HTML、CSS 和 JavaScript 创建一个动态的网页。 案例:简单的待办事项列表 1. HTML 部分 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8…...

4.2.1 通过DTS传递物理中断号给Linux
点击查看系列文章 》 Interrupt Pipeline系列文章大纲-CSDN博客 4.2.1 通过DTS传递物理中断号给Linux 参考《GICv3_Software_Overview_Official_Release_B》,下表描述了GIC V3支持的INTID(硬件中断号)的范围。 SGI (Software Generated Interrupt):软…...

常用性能优化方法
在一个Java项目中进行性能优化是至关重要的。性能优化能够提高项目的效率和响应速度,提升用户体验,并且可以节省服务器资源和成本。 首先,性能优化可以确保项目的高效运行。当项目在运行时,性能问题可能会导致应用程序变慢、响应时…...

上海我店:创新模式引领本地生活新风尚
近年来,一个名为“上海我店”的新兴平台在网络空间中迅速崛起,其公布的业绩令人瞩目——在短短三年内,交易流水已跨越百亿大关,并在最近一个月内迎来了近百万的新增注册用户。这一强劲的增长势头,无疑吸引了众多商家和…...
【微服务】前端微服务qiankun 2.x主子应用通信代码片段
主应用代码 主应用工程里面源代码新建qiankun/index.js,通信代码如下: import { initGlobalState } from "qiankun"; import store from /store// 主应用与微应用数据通信 const state {subappClassName: // 设置子应用打包根的class类名 …...
高级java每日一道面试题-2024年9月30日-算法篇-LRU是什么?如何实现?
如果有遗漏,评论区告诉我进行补充 面试官: LRU是什么?如何实现? 我回答: LRU(Least Recently Used)是一种常用的缓存淘汰策略,用于在缓存满时决定哪些数据应该被移除。LRU算法的基本思想是:当缓存达到其容量上限时࿰…...

CSS选择器的全面解析与实战应用
CSS选择器的全面解析与实战应用 一、基本选择器1.1 通配符选择器(*)2.标签选择器(div)1.3 类名选择器(.class)4. id选择器(#id) 二、 属性选择器(attr)三、伪…...
vue3自动暴露element-plus组件的ref
自动暴露子组件的方法,注意在TS下,需要自己声明类型,我这里全用any代替了 <template><el-button click"getFocus">获得焦点</el-button><com ref"comRef" /> </template><script setup…...
龙芯+FreeRTOS+LVGL实战笔记(新)——10蜂鸣器嘀嘀嘀
本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了完善与优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

MeshGPT 笔记
[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...

CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...

本地部署drawDB结合内网穿透技术实现数据库远程管控方案
文章目录 前言1. Windows本地部署DrawDB2. 安装Cpolar内网穿透3. 实现公网访问DrawDB4. 固定DrawDB公网地址 前言 在数字化浪潮席卷全球的背景下,数据治理能力正日益成为构建现代企业核心竞争力的关键因素。无论是全球500强企业的数据中枢系统,还是初创…...

2025-06-01-Hive 技术及应用介绍
Hive 技术及应用介绍 参考资料 Hive 技术原理Hive 架构及应用介绍Hive - 小海哥哥 de - 博客园https://cwiki.apache.org/confluence/display/Hive/Home(官方文档) Apache Hive 是基于 Hadoop 构建的数据仓库工具,它为海量结构化数据提供类 SQL 的查询能力…...
从0开始一篇文章学习Nginx
Nginx服务 HTTP介绍 ## HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 ## HTTP工作在 TCP/IP协议体系中的TCP协议上&#…...

CSS(2)
文章目录 Emmet语法快速生成HTML结构语法 Snipaste快速生成CSS样式语法快速格式化代码 快捷键(VScode)CSS 的复合选择器什么是复合选择器交集选择器后代选择器(重要)子选择器(重要)并集选择器(重要)**链接伪类选择器**focus伪类选…...

【Redis】Redis 的持久化策略
目录 一、RDB 定期备份 1.2 触发方式 1.2.1 手动触发 1.2.2.1 自动触发 RDB 持久化机制的场景 1.2.2.2 检查是否触发 1.2.2.3 线上运维配置 1.3 检索工具 1.4 RDB 备份实现原理 1.5 禁用 RDB 快照 1.6 RDB 优缺点分析 二、AOF 实时备份 2.1 配置文件解析 2.2 开启…...