Spring中BeanFactoryPostProcessor详解

news2024/11/26 20:13:56

目录

功能与作用

使用案例

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。

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

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

相关文章

Kaggle:收入分类

先看一下数据的统计信息 import pandas as pd # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desktop\收入分类\training.csv", encodingutf-8, encoding_errorsrepl…

蓝桥杯练习笔记(十六)

蓝桥杯练习笔记&#xff08;十六&#xff09; 一、 输入示例&#xff1a; 3 1 2 1 11 3 4 74 5 3这是用到了m叉树的结论&#xff1a;对于某个m叉树的一个节点n&#xff0c;假如其有完整子树&#xff0c;则其左子节点l为l(n-1)m2&#xff0c;右子节点r为rmn1。基于此我们可以快…

SpringBoot+thymeleaf完成视频记忆播放功能

一、背景 1)客户要做一个视频播放功能,要求是系统能够记录观看人员在看视频时能够记录看到了哪个位置,在下次观看视频的时候能够从该位置进行播放。 2)同时,也要能够记录是谁看了视频,看了百分之多少。 说明:由于时间关系和篇幅原因,我们这里只先讨论第一个要求,第…

如何使用极狐GitLab 启用自动备份功能

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何极狐GitLab 自…

【面试八股总结】传输控制协议TCP(三)

参考资料 &#xff1a;小林Coding、阿秀、代码随想录 一、TCP拥塞控制⭐ 1. 慢启动 – Slow Start 慢启动是指TCP连接刚建立&#xff0c;一点一点地提速&#xff0c;试探一下网络的承受能力&#xff0c;以免直接扰乱了网络通道的秩序。 慢启动算法&#xff1a; 初始拥塞窗口…

IDEA中连接SQLserver数据库(DataGrip相同连接)

IDEA中连接SQLserver数据库(DataGrip相同连接) 1. 打开IDEA-database组件 2. 新建SQL server连接 3. 填写信息进行连接 填写连接名称&#xff0c;连接主机IP&#xff0c;端口&#xff0c;默认端口1433&#xff0c;数据库用户名密码&#xff0c;默认数据库用户名是sa 第一次连接…

CMakeLists.txt编写简单介绍:CMakeLists.txt同时编译.cpp和.cu

关于CMakeLists.txt的相关介绍,这里不赘诉,本人的出发点是借助于CMakeLists.txt掌握基本的C++构建项目流程,下面是本人根据网络资料以及个人实践掌握的资料。 CMakeList.txt构建C++项目 下图是一个使用CUDA实现hello world的项目,一般来说,一个标准的C++项目包括三个文件…

nginx | nginx反向代理/负载均衡/缓存

文章目录 一、Nginx 反向代理1.1 nginx 文件结构1.2 默认的nginx配置文件1.3 实践中的 nginx.conf 二、Nginx 负载均衡2.1 热备负载均衡2.2 轮询负责均衡2.3 加权轮询负载规则2.4 ip_hash 负载均衡2.5 对特定资源实现负载均衡2.6 对不同域名实现负载均衡2.7 实现带有URL重写的负…

探索 ZKFair 的Dargon Slayer蓝图,解锁新阶段的潜力

在当前区块链技术的发展中&#xff0c;Layer 2&#xff08;L2&#xff09;解决方案已成为提高区块链扩容性、降低交易成本和提升交易速度的关键技术&#xff0c;但它仍面临一些关键问题和挑战&#xff0c;例如用户体验的改进、跨链互操作性、安全性以及去中心化程度。在这些背景…

【已解决】Error: error:0308010C:digital envelope routines::unsupported

前言 场景&#x1f3ac; 使用 Ant Design &#xff0c; 执行 npm run dev 出现异常。 文章目录 前言场景&#x1f3ac; 异常信息解决方案方案一(推荐)MAC | Linux 电脑成功⬇️ Windows 电脑 方案2&#xff1a; 不懂留言 JavaPub 异常信息 我直接异常信息&#xff0c;你可以…

关于C#操作SQLite数据库的一些函数封装

主要功能&#xff1a;增删改查、自定义SQL执行、批量执行&#xff08;事务&#xff09;、防SQL注入、异常处理 1.NuGet中安装System.Data.SQLite 2.SQLiteHelper的封装&#xff1a; using System; using System.Collections.Generic; using System.Data.SQLite; using System.…

Linux提权!!!

上一篇文章讲了Windows的提权&#xff0c;那么这篇文章就来讲一下Linux的提权 1.SUID提权 suid权限 作用&#xff1a;让普通用户临时拥有该文件的属主的执行权限&#xff0c;suid权限只能应用在二进制可执行文件&#xff08;命令&#xff09;上&#xff0c;而且suid权限只能设置…

【前端面试3+1】09 ES6新特性、Promise原理 、浏览器从输入到页面渲染的过程、【罗马数字转整数】

一、ES6新特性 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript的一个重要更新版本&#xff0c;引入了许多新特性和语法改进&#xff0c;下面详细说明一些主要的新特性&#xff1a; 1. let 和 const 声明&#xff1a; 使用let和const关键字可以声明块级作用域的变量&a…

Go-Gin中优雅的实现参数校验,自定义错误消息提示

问题描述 在参数校验的时候我们一般会基于"github.com/go-playground/validator/v10"这个库给结构体加标签实现校验参数&#xff0c;当参数校验错误的时候&#xff0c;他的提示一般是英文的&#xff0c;怎么自定义参数错误提示呢&#xff1f;跟着我一步步来 注册校…

集合的学习

为什么要有集合&#xff1a;集合会自动扩容 集合不能存基本数据类型&#xff08;基本数据类型是存放真实的值&#xff0c;而引用数据类型是存放一个地址&#xff0c;这个地址存放在栈区&#xff0c;地址所指向的内容存放在堆区&#xff09; 数组和集合的对比&#xff1a; 集…

什么是js、ajax

1.什么是js JavaScript&#xff08;简称 JS&#xff09;是一种轻量级、解释型的编程语言&#xff0c;通常用于在 Web 页面上添加交互性、动态性和动画效果。它是世界上最流行的编程语言之一&#xff0c;也是唯一一种可以在 Web 浏览器中运行的编程语言。 2.什么是AJAX ajax…

华为审核被拒提示: 您的应用存在(最近任务列表隐藏风险活动)的行为,不符合华为应用市场审核标准

应用审核意见&#xff1a; 您的应用存在&#xff08;最近任务列表隐藏风险活动&#xff09;的行为&#xff0c;不符合华为应用市场审核标准。 修改建议&#xff1a;请参考测试结果进行修改。 请参考《审核指南》第2.19相关审核要求&#xff1a;https://developer.huawei.com/c…

算法整理:二分查找

1二分查找&#xff1a;在有序集合搜索特定值的过程&#xff0c;每次比较之后将查找空间一分为二。 target:要查找的值 index:当前位置 left,right:维持查找空间的指标 mid:用来确定向左查还是向右查的索引 查找空间: [left,right] 二分查找维护left&#xff0c;right&#xff0…

ElementUI 表格横向滚动条时滚动到指定位置

ElementUI 表格横向滚动条时滚动到指定位置 getColumnOffset(columnProp) {this.$nextTick(() > {const table this.$refs.tableRef.$refs.multipleTable;const columns table.columns;const column columns.find((col) > col.property columnProp);if (column) {// …

Transformer模型-softmax的简明介绍

今天介绍transformer模型的softmax softmax的定义和目的&#xff1a; softmax&#xff1a;常用于神经网络的输出层&#xff0c;以将原始的输出值转化为概率分布&#xff0c;从而使得每个类别的概率值在0到1之间&#xff0c;并且所有类别的概率之和为1。这使得Softmax函数特别适…