Spring之BeanFactoryPostProcessor详解

目录

功能与作用

使用案例

spring提供的常见BeanFactoryPostProcessor

1.EventListenerMethodProcessor

2.BeanDefinitionRegistryPostProcessor

功能与作用

使用案例

spring提供的唯一BeanDefinitionRegistryPostProcessor

总结


功能与作用

参考BeanFactoryPostProcessor方法注释可知:该方法是在所有bean被加载,未被实例化前执行。对所有bean的属性可以修改也可以添加

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean 
     
     definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

使用案例

用户可以自定义一个实现BeanFactoryPostProcessor的类,获取某个bean修改bean的属性,比如如下举例修改该UserService类的属性由单例改为原型


@Component
public class UserService {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}


package com.cyl.beanFactoryDemo;

import org.springframework.beans.BeansException;
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 CylBeanFactoryBeanPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
		//修改该bean的属性为原型
		beanDefinition.setScope("prototype");
		//添加该bean的属性name默认值为cyl
		MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
		propertyValues.add("name","cyl");
	}

}

spring提供的常见BeanFactoryPostProcessor

1.EventListenerMethodProcessor

处理添加了EventListener注解的逻辑,它的原理参见我的博文:

Spring注解@EventListener实现监听原理-CSDN博客文章浏览阅读903次,点赞21次,收藏14次。@EventListener实现原理主要通过EventListenerMethodProcessor和DefaultEventListenerFactory这两个类实现。EventListenerMethodProcessor的作用是识别所有使用eventListener注解的方法DefaultEventListenerFactory将EventListenerMethodProcessor识别出的方法封装成为监听器类以代码new AnnotationConfigApplicationContext为入https://blog.csdn.net/changyinling520/article/details/137205662?spm=1001.2014.3001.5502

2.BeanDefinitionRegistryPostProcessor

功能与作用

BeanDefinitionRegistryPostProcessor,该接口继承了BeanFactoryPostProcessor,拥有修改bean属性的功能,又拓展postProcessBeanDefinitionRegistry方法,通过代码注释理解:允许在bean被加载后,继续添加新的bean

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

postProcessBeanDefinitionRegistry方法先执行,postProcessBeanFactory后执行。

可以从详见:org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)

使用案例

用户可以自定义一个实现BeanDefinitionRegistryPostProcessor的类,注册OrderService类到spring容器中,并修改它的属性值

1.创建一个不被spring管理的OrderService,内部有UserService属性

package com.cyl.beanFactoryDemo;

public class OrderService {
	private UserService userService;

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}
}

2.创建CylBeanRegistryPostProcessor实现了BeanDefinitionRegistryPostProcessor,在postProcessBeanDefinitionRegistry方法内注册OrderService类到容器中,在postProcessBeanFactory中给OrderService添加属性userService

package com.cyl.beanFactoryDemo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class CylBeanRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
	
    @Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
		rootBeanDefinition.setBeanClass(OrderService.class);
		registry.registerBeanDefinition("orderService", rootBeanDefinition);
	}

    
    @Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

		BeanDefinition userServiceBean = beanFactory.getBeanDefinition("userService");
		//修改该userService的属性name默认值为cyl
		userServiceBean.getPropertyValues().addPropertyValue("name", "cyl");
		
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("orderService");
		//修改该orderService的添加属性userService
		beanDefinition.getPropertyValues().add("userService", beanFactory.getBean(UserService.class));
	}

	
}

最终输出结果

public static void main(String[] args) {

		// 创建一个Spring容器
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(AppConfig.class);
		context.refresh();
    
		OrderService orderService = context.getBean(OrderService.class);
		System.out.println(orderService.getUserService().getName());
}

spring提供的唯一BeanDefinitionRegistryPostProcessor

ConfigurationClassPostProcessor,这个类扫描所有component,service,import,configuration等注解,加载所有的bean定义到容器内。后续博文会详细介绍它的处理逻辑

总结

    BeanFactoryProcessor是spring的一个拓展点,它的作用时机是在加载完所有的beanDefinition,还未实例化前。可以对beanDefinition进行加工,但是不可以加载beanDefinition。BeanDefinitionRegistryPostProcessor是BeanFactoryProcessor的子接口,增强了功能,既可以对beanDefinition加工,还可以加载自定义的beanDefinition。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[StartingPoint][Tier1]Pennyworth

Important Jenkins是一个用于自动化构建、测试和部署软件项目的开源持续集成和持续部署&#xff08;CI/CD&#xff09;工具。它允许开发团队自动执行和监控在软件开发过程中的重复性任务&#xff0c;例如构建代码、运行测试、部署应用程序等。Jenkins提供了一个易于使用的Web界…

力扣---分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&a…

【Java基础】面试题汇总

Java基础面试题1. JVM vs JDK vs JRE 2. 什么是字节码?采用字节码的好处是什么?3. 为什么说 Java 语言“编译与解释并存”&#xff1f;4. AOT 有什么优点&#xff1f;为什么不全部使用 AOT 呢&#xff1f;5. Java 和 C 的区别&#xff1f;6. Java 中的基本数据类型&#xff1…

算法第三十九天-验证二叉树的前序序列化

验证二叉树的前序序列化 题目要求 解题思路 方法一&#xff1a;栈 栈的思路是「自底向上」的想法。下面要结合本题是「前序遍历」这个重要特点。 我们知道「前序遍历」是按照「根节点-左子树-右子树」的顺序遍历的&#xff0c;只有当根节点的所有左子树遍历完成之后&#xf…

代码随想录第32天|455.分发饼干 376. 摆动序列

理论基础 贪心算法核心&#xff1a;选择每一阶段的局部最优&#xff0c;从而达到全局最优。 455.分发饼干 455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09;代码随想录 (programmercarl.com)455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09; 贪心算法理论基础&am…

LeetCode:1483. 树节点的第 K 个祖先(倍增 Java)

目录 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 实现代码与解析&#xff1a; 倍增 原理思路&#xff1a; 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#…

【Vue】Vue3中的OptionsAPI与CompositionAPI

文章目录 OptionsAPICompositionAPI对比总结 OptionsAPI 中文名:选项式API通过定义methods,computed,watch,data等属性方法&#xff0c;处理页面逻辑。以下是OptionsAPI代码结构 实例代码: <script lang"ts">// js或者tsimport { defineComponent } from vu…

HubSpot如何通过自动化和优化客户服务流程,提升客户满意度和忠诚度?

HubSpot通过自动化和优化客户服务流程&#xff0c;可以有效地提升客户满意度和忠诚度。以下是HubSpot实现这一目标的几个关键步骤&#xff1a; 建立清晰的服务流程&#xff1a;首先&#xff0c;HubSpot帮助企业建立清晰、标准化的客户服务流程。这包括明确的服务阶段定义&…

git分支 - 分支简介

分支 几乎每个版本控制系统都有某种形式的分支支持。分支意味着偏离了主开发线&#xff0c;并继续进行工作&#xff0c;而不会影响到主开发线。在许多版本控制系统工具中&#xff0c;这是一个比较昂贵的过程&#xff0c;通常需要创建源代码目录的一个新副本&#xff0c;对于大…

第7章 数据安全

思维导图 7.1 引言 数据安全包括安全策略和过程的规划、建立与执行&#xff0c;为数据和信息资产提供正确的身份验证、授权、访问和审计。虽然数据安全的详细情况(如哪些数据需要保护)因行业和国家有所不同&#xff0c;但是数据安全实践的目标是相同的&#xff0c;即根据隐私和…

链表之双向链表的实现

铁汁们大家好&#xff0c;我们上一篇博客学习了单链表&#xff0c;这节课让我们继续往深学习&#xff0c;学习一下双线链表&#xff0c;话不多说&#xff0c;我们开始吧&#xff01; 目录 1.双向链表 2.顺序表和链表的优缺点 3.双向链表的实现 1.双向链表 1.我们要实现的双线…

Elasticsearch快速上手

基本概念 索引&#xff08;Index&#xff09; 索引是文档的容器&#xff0c;就像关系数据库中&#xff0c;要存储行记录必须先创建数据库和表一样。 类型&#xff08;Type&#xff09; ES6 及之前的版本还存在”类型“的概念&#xff0c;一个索引下可以存储多个类型的文档&am…

探索数据结构:特殊的双向队列

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 双向队列的定义 **双向队列(double‑ended queue)**是一种特殊的队列…

Ant Design Pro | 前端项目初始化

初始化项目 环境确认 这里使用的版本如下&#xff1a; 新建文件夹&#xff08;fapi&#xff09; 执行项目初始化命令 cmd进入命令行执行项目初始化命令&#xff0c;参考官网https://pro.ant.design/zh-CN/ # 使用 npm npm i ant-design/pro-cli -g # fapi-frontend是项目…

树莓派固件烧录教程(2024)

一、烧录工具准备 硬件准备&#xff1a; 16G及以上TF卡和读卡器&#xff0c;TF卡建议高速卡&#xff08;卡的读写速度直接影响树莓派的运行速度&#xff09;。 软件准备&#xff1a;&#xff08;下面二方法选其一即可&#xff09; 方法1&#xff1a;raspberry官方烧录工具R…

【高校科研前沿】中国科学院南京地理与湖泊研究所肖启涛博士为一作在Sci. Bull发文:我国湖泊二氧化碳从大气的源向汇转变

目录 1.文章简介 2.研究内容 3.文章引用 1.文章简介 论文名称&#xff1a;Lakes shifted from a carbon dioxide source to a sink over past two decades in China 第一作者及通讯作者&#xff1a;肖启涛&#xff08;博士生&#xff09;&#xff0c;段洪涛&#xff08;研究…

JavaSE继承和多态(下)

在了解多态之前我们先弄清以下三个概念&#xff1a; 方法的重写向上转型和向下转型动态绑定和静态绑定 一.方法的重写 重写(override)&#xff1a;也称为覆盖。重写是子类对父类非静态、非private修饰&#xff0c;非final修饰&#xff0c;非构造方法等的实现过程 进行重新编写,…

如何使用 langchain 与 openAI 连接

上一篇写了如何安装 langchain https://www.cnblogs.com/hailexuexi/p/18087602 这里主要说一个 langchain的使用 创建一个目录 langchain &#xff0c;在这个目录下创建两个文件 main.py 这段python代码&#xff0c;用到了openAI&#xff0c;需要openAI及FQ。这里只做…

c++的学习之路:16、string(3)

上章有一些东西当时没学到&#xff0c;这里学到了将在补充&#xff0c;文章末附上代码&#xff0c;思维导图。 目录 一、赋值重载 二、带模板的创建 三、析构函数 四、代码 五、思维导图 一、赋值重载 这里的赋值重载就是直接利用交换函数进行把传参生成的临时数据和需要…

IDEA中的Debug功能介绍

说明&#xff1a;本文介绍IDEA中的Debug功能&#xff0c;基于2023.2&#xff08;Ultimate Edition&#xff09;版本 简单介绍 首先&#xff0c;在程序需要停止的所在行号上&#xff0c;鼠标左键&#xff0c;可设置一个断点&#xff0c;是一个红色圆点标志&#xff0c;表示程序…