Spring系列 BeanPostProcessor

news2024/12/25 14:15:17

文章目录

  • 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;
	}

	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
		return null;
	}

	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		return pvs;
	}
}

它提供了多个方法,下面是各个方法的作用

  1. postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
    在 bean 实例化之前调用。可以用于检查 bean 的元数据,决定是否需要实例化该 bean,或者返回一个替代的实例。可以返回一个替代的 bean 实例,或者返回 null 继续正常的实例化流程。

在这里插入图片描述

  1. postProcessAfterInstantiation(Object bean, String beanName)
    在 bean 实例化之后调用,可以用于逻辑处理,比如检查 bean 是否需要进行某些初始化操作。通常返回 true,表示允许继续进行属性填充。如果返回 false,则 Spring 将跳过属性的设置。

在这里插入图片描述

  1. 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 {

	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {

		return null;
	}

	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}
}
  1. Class<?> predictBeanType(Class<?> beanClass, String beanName)

在这里插入图片描述

  1. Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)

在这里插入图片描述

  1. Object getEarlyBeanReference(Object bean, String beanName)

在 bean 实例化后、初始化之前调用,允许返回早期的 bean 引用。这可以解决循环依赖问题,特别是在需要提前获取 bean 的情况下。返回早期的 bean 实例,或原始的 bean(即不做任何更改)。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ASE】第四课_高亮显示效果(手动切换)

今天我们一起来学习ASE插件&#xff0c;希望各位点个关注&#xff0c;一起跟随我的步伐 今天我们来学习高亮的效果。 思路&#xff1a; 1.添加纹理贴图和法线贴图&#xff0c;环境光遮挡贴图 2.添加高亮的参数&#xff0c;并设置 3.手搓一个边缘光,通过高亮参数调节 4.将模…

微信小程序——音乐播放器

目的 掌握swiper组件、scroll-view组件的使用掌握image组件的使用掌握音频API的使用掌握slider组件的使用 内容 了音乐小程序项目的完整开发流程&#xff0c;其开发步骤包括页面结构的分析、样式的设计、组件的运用等。通过本章的学习&#xff0c;读者能够掌握小程序的基本交…

聚星文社——绘唐科技有什么区别!

聚星文社和绘唐科技是两个不同的公司&#xff0c;有一些区别。下面是它们的一些区别&#xff1a; 绘唐科技——聚星文社https://iimenvrieak.feishu.cn/docx/ZhRNdEWT6oGdCwxdhOPcdds7nof 行业领域&#xff1a;聚星文社主要从事文化娱乐行业&#xff0c;包括出版、影视制作等&…

点餐小程序实战教程14点餐功能

目录 1 功能分析2 初始化菜品的数量3 加入购物车4 显示购物车5 最终的效果总结 上一篇我们讲解了如果通过扫码实现餐桌信息显示&#xff0c;本篇我们介绍一下点餐的功能。 1 功能分析 点餐的话一般我们是在菜品点击号或者-号来加入购物车&#xff0c;加入购物车之后还可以修改…

APP 安全测试项总结

一、安装包测试 1.1、关于反编译 目的是为了保护公司的知识产权和安全方面的考虑等&#xff0c;一些程序开发人员会在源码中硬编码一些敏感信息&#xff0c;如密码。而且若程序内部一些设计欠佳的逻辑&#xff0c;也可能隐含漏洞&#xff0c;一旦源码泄漏&#xff0c;安全隐患…

Temporal Dynamic Quantization for Diffusion Models阅读

文章目录 AbstractIntroductionBackgrounds and Related Works2.1 扩散模型2.2 量化2.3 量化感知训练和训练后量化 TemporalDynamic Quantization3.1 量化方法3.2 扩散模型量化的挑战3.3 TDQ模块的实现3.4 工程细节时间步的频率编码TDQ模块的初始化 Experimental SetupResults5…

#git 问题failed to resolve head as a valid ref

问题如下&#xff1a; 解决方法&#xff1a; 1、运行 git fsck --full 可以查看具体error信息&#xff0c;一般都是head索引问题 2、.git\refs\heads\xxx&#xff08;当前分支&#xff09;txt编辑器打开显示乱码&#xff0c;而不是hash编码 3、在.git\logs\refs\heads\xxx&a…

如何评价 Python 语言的运行速度

Python 作为一门编程语言&#xff0c;其运行速度一直是业界讨论的焦点。它的简洁语法和广泛的应用使得它在开发过程中非常高效&#xff0c;然而&#xff0c;运行速度与一些更底层的编程语言相比存在一定的劣势。这是否是由于 Python 语法的简洁性所带来的代价&#xff1f;我们可…

心觉:自我暗示语“正确姿势”的科学解释

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作185/1000天 “如何重塑高效学习的潜意识”这个系列文章其实昨天已经写完了 在写这个系列文章的时候&#xff0c;我突然有一个关于…

宠物空气净化器该怎么选?希喂、美的、有哈这三款有推荐的吗?

终于要到国庆了&#xff0c;这可是打工人除春节外最长的假期&#xff01;在外上班后&#xff0c;回家的次数越来越少了&#xff0c;这次国庆肯定要回去陪陪父母。这票是真难买啊&#xff0c;候补了我一个多星期才买到。本来以为最困难的问题已经解决了&#xff0c;又想到我家猫…

Mamba以及我们看的第一篇MambaOcc

0. 简介 深度学习架构有很多&#xff0c;但近些年最成功的莫过于 Transformer&#xff0c;其已经在多个应用领域确立了自己的主导地位。如此成功的一大关键推动力是注意力机制&#xff0c;这能让基于 Transformer 的模型关注与输入序列相关的部分&#xff0c;实现更好的上下文…

动手测试:CPU的L1~L3级缓存和内存的读取速度测试

引言 在许多文章中指出了这些缓存的架构&#xff0c;速度差异等。纸上得来终觉浅&#xff0c;今天想实际写代码简单测试一下。 背景 现代计算机系统中&#xff0c;CPU缓存&#xff08;L1、L2、L3&#xff09;和主内存&#xff08;RAM&#xff09;之间的读取速度有着显著的差…

数据结构之链表(2),双向链表

目录 前言 一、链表的分类详细 二、双向链表 三、双向链表的实现 四、List.c文件的完整代码 五、使用演示 总结 前言 接着上一篇单链表来详细说说链表中什么是带头和不带头&#xff0c;“哨兵位”是什么&#xff0c;什么是单向什么是双向&#xff0c;什么是循环和不循环。然后实…

U盘恢复数据工具:让数据失而复得的魔法

优盘里数据丢失无疑会给我们的工作和生活带来诸多不便。幸运的是&#xff0c;优盘数据恢复软件应运而生&#xff0c;它们如同数据的守护者&#xff0c;为我们提供了找回丢失数据的希望。这次我们就一同来探讨u盘恢复数据有什么方法吧。 1.福昕恢复数据 链接直达&#xff1a;h…

AutoSar 通信服务架构,CAN通信诊断详解

文章目录 Com&#xff08;通信服务模块&#xff09;PDU的定义和结构PDU的分类IPDU Mux 模块PDU R 模块&#xff08;路由&#xff09;Bus TP 模块BUS InterfaceCanIf模块LinIf模块 发送数据示例&#xff08;CAN报文&#xff09;接收数据示例&#xff08;CAN报文&#xff09;通信…

监控告警功能详细介绍及操作演示:运维团队的智能保障

在当今这个信息化高速发展的时代&#xff0c;运维团队面临着前所未有的挑战。为了确保系统的稳定性和高效运维&#xff0c;监控告警功能成为了运维团队不可或缺的得力助手。本文将详细介绍我们的监控告警功能&#xff0c;并结合实际操作页面进行演示&#xff0c;帮助运维团队更…

Docker入门指南:快速学习Docker的基本操作

为什么需要Docker 有时我们在本地开发好程序并成功运行之后&#xff0c;却在服务器上运行不起来&#xff0c;通过观察日志通常会发现&#xff0c;哦原来是这个库没安装&#xff0c;于是我们就需要先安装需要用到的库&#xff0c;然后再启动服务你可能还会发现用到的数据库信息…

《Linux从小白到高手》理论篇(六):Linux软件安装一篇通

List item 本篇介绍Linux软件安装相关的操作命令&#xff0c;看完本文&#xff0c;有关Linux软件安装相关操作的常用命令你就掌握了99%了。 Linux软件安装 RPM RPM软件的安装、删除、更新只有root权限才能使用&#xff1b;查询功能任何用户都可以操作&#xff1b;如果普通用…

真正的Open AI ——LLaMA颠覆开源大模型

1. LLaMA 简介 LLaMA&#xff08;Large Language Model Meta AI&#xff09;是由Meta&#xff08;原Facebook&#xff09;推出的一个大型语言模型系列&#xff0c;旨在通过更小的模型规模和更少的计算资源&#xff0c;实现与其他主流语言模型&#xff08;如GPT&#xff09;相媲…

spring简短注入

新建bean 创建set方法 jpackage com.dependency.spring6.bean;import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class User {private static final Logger LOGGER LoggerFactory.getLogger(User.class);private String username;private String password;pr…