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

相关文章

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

MyBatis的配置对象Configuration作用及说明

《MyBatis的配置对象Configuration作用及说明》MyBatis的Configuration对象是MyBatis的核心配置对象,它包含了MyBatis运行时所需的几乎所有配置信息,这个对... 目录MyBATis配置对象Configuration作用Configuration 对象的主要作用C

MySQL表锁、页面锁和行锁的作用及其优缺点对比分析

《MySQL表锁、页面锁和行锁的作用及其优缺点对比分析》MySQL中的表锁、页面锁和行锁各有特点,适用于不同的场景,表锁锁定整个表,适用于批量操作和MyISAM存储引擎,页面锁锁定数据页,适用于旧版本... 目录1. 表锁(Table Lock)2. 页面锁(Page Lock)3. 行锁(Row Lock

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

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