BeanFactoryPostProcessor作用

2024-05-25 02:20

本文主要是介绍BeanFactoryPostProcessor作用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

介绍

BeanFactoryPostProcessor是spring中一个很重要的接口,位于spring流程中的获取BeanDefinition之后,实例化之前(点击spring流程),我们可以实现该接口并注入spring容器中进行拓展(对BeanDefinition进行自定义修改),我们知道容器中的Bean都是根据BeanDefinition信息去是实例化的,BeanDefinition中存储了bean的信息,我们这儿可以修改BeanDefinition,所以相当于修改bean。
在这里插入图片描述

spring官方解释

在这里插入图片描述

解释

修改 Bean 定义:
允许在 Bean 实例化之前自定义修改应用上下文中的 Bean 定义,适用于系统管理员通过自定义配置文件覆盖 Bean 属性配置。

配置文件支持:
支持使用 PropertyResourceConfigurer 等解决方案处理配置文件中的 Bean 属性覆盖需求。

操作限制:
只能与 Bean 定义交互,不能与 Bean 实例交互,以避免 Bean 过早实例化和意外副作用。如果需要与 Bean 实例交互,应使用 BeanPostProcessor。

自动检测与注册:
ApplicationContext 会自动检测并应用 BeanFactoryPostProcessor。
也可以通过 ConfigurableApplicationContext 编程方式注册。

排序机制:

  1. 自动检测的 BeanFactoryPostProcessor 会根据 PriorityOrdered 和 Ordered 接口排序。
    自动检测是指 ApplicationContext 在启动时会自动检测其 Bean 定义中是否存在 BeanFactoryPostProcessor 的实现类。

  2. 编程注册的 BeanFactoryPostProcessor 按注册顺序应用,忽略排序接口和 @Order 注解。
    编程注册是指通过编码的方式在应用程序启动时显式地向 ApplicationContext 注册 BeanFactoryPostProcessor。

源码

package org.springframework.beans.factory.config;import org.springframework.beans.BeansException;@FunctionalInterface
public interface BeanFactoryPostProcessor {/***获取到beanFactory之后可获取所有BeanDefinition,可以对BeanDefinition进行更改*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}

例子

光描述起来可能有点苍白无力,其实我们也见过,比如我们配置数据库是写的${jdbc.userName}就是实现了BeanFactoryPostProcessor 接口去替换的,我这儿也写个类似的功能,看一下代码。

package com.lp.entity;public class Student {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
package com.lp;public class Constants {public static String userName = "root";
}
package com.lp;import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.stereotype.Component;import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;@Component
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();for (String beanDefinitionName : beanDefinitionNames) {BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {Object value = propertyValue.getValue();if (value != null && value instanceof TypedStringValue){String input = ((TypedStringValue) value).getValue();String regex = "\\^\\{([^}]*)\\}";// 编译正则表达式Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(input);// 查找匹配项并提取捕获组if (matcher.find()) {String extracted = matcher.group(1); // 捕获组1的内容// 获取 Constants 类的所有字段Field[] fields = Constants.class.getDeclaredFields();for (Field field : fields) {if (field.getName().equals(extracted)){Object object = null;try {object = field.get(null);} catch (IllegalAccessException e) {throw new RuntimeException(e);}propertyValues.addPropertyValue(propertyValue.getName(), object);break;}else {propertyValues.addPropertyValue(propertyValue.getName(), "");}}}}}}}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.lp"/><bean id="student" class="com.lp.entity.Student"><property name="name" value="^{userName}"/></bean></beans>
public class test {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");Student student = (Student)context.getBean("student");System.out.println("-----------"+student.getName());}
}

在这里插入图片描述
简单说一下,我有个Student类,有name属性,我配置的name=^{userName},我的匹配规则就是当匹配到的时候就把userName拿出来匹配常量的属性,如果匹配上就将属性值给name,这儿注意的就是BeanFactoryPostProcessor 执行时机,操作BeanDefinition就完成,如果了解spring流程这个功能就变为异常简单了。

这篇关于BeanFactoryPostProcessor作用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1000207

相关文章

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

未来工作趋势:零工小程序在共享经济中的作用

经济在不断发展的同时,科技也在飞速发展。零工经济作为一种新兴的工作模式,正在全球范围内迅速崛起。特别是在中国,随着数字经济的蓬勃发展和共享经济模式的深入推广,零工小程序在促进就业、提升资源利用效率方面显示出了巨大的潜力和价值。 一、零工经济的定义及现状 零工经济是指通过临时性、自由职业或项目制的工作形式,利用互联网平台快速匹配供需双方的新型经济模式。这种模式打破了传统全职工作的界限,为劳动

Science|癌症中三级淋巴结构的免疫调节作用与治疗潜力|顶刊精析·24-09-08

小罗碎碎念 Science文献精析 今天精析的这一篇综述,于2022-01-07发表于Science,主要讨论了癌症中的三级淋巴结构(Tertiary Lymphoid Structures, TLS)及其在肿瘤免疫反应中的作用。 作者类型作者姓名单位名称(中文)通讯作者介绍第一作者Ton N. Schumacher荷兰癌症研究所通讯作者之一通讯作者Daniela S. Thomm

j2EE通用jar包的作用

原文:http://blog.sina.com.cn/s/blog_610901710101kx37.html IKIKAnalyzer3.2.8.jar // 分词器 ant-junit4.jar // ant junit antlr-2.7.6.jar // 没有此包,hibernate不会执行hql语句。并且会报NoClassDefFoundError: antlr

【vue3|第28期】 Vue3 + Vue Router:探索路由重定向的使用与作用

日期:2024年9月8日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉在这里插入代码片得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083;0.98365 = 0.0006 说

请解释Java Web应用中的前后端分离是什么?它有哪些好处?什么是Java Web中的Servlet过滤器?它有什么作用?

请解释Java Web应用中的前后端分离是什么?它有哪些好处? Java Web应用中的前后端分离 在Java Web应用中,前后端分离是一种开发模式,它将传统Web开发中紧密耦合的前端(用户界面)和后端(服务器端逻辑)代码进行分离,使得它们能够独立开发、测试、部署和维护。在这种模式下,前端通常通过HTTP请求与后端进行数据交换,后端则负责业务逻辑处理、数据库交互以及向前端提供RESTful

PRN(20201231):驾驶人驾驶决策机制遵循最小作用量原理

王建强, 郑讯佳, 黄荷叶. 驾驶人驾驶决策机制遵循最小作用量原理[J]. 中国公路学报, 2020, v.33;No.200(04):159-172. 观点: 为提升智能汽车的自主决策能力,使其能够学习人的决策智慧以适应复杂多变的道路交通环境,需要揭示驾驶人决策机制。 依据: 物理学中常用最小作用量原理解释自然界(包括物理和生物行为)极值现象。同时,最小作用量原理还用于解释蚂蚁在觅

glPushMatrix()和glPopMatrix()的作用

当你做了一些移动或旋转等变换后,使用glPushMatrix(); OpenGL 会把这个变换后的位置和角度保存起来。 然后你再随便做第二次移动或旋转变换,再用glPopMatrix(); OpenGL 就把刚刚保存的那个位置和角度恢复。 比如: glLoadIdentity(); glTranslatef(1,0,0);//向右移动(1,0,0) glPushMatrix(

自定义view中常用到哪些方法作用分别是什么

目录 构造函数onMeasure(int widthMeasureSpec, int heightMeasureSpec)onDraw(Canvas canvas)onLayout(boolean changed, int left, int top, int right, int bottom)onTouchEvent(MotionEvent event)onSizeChanged(int