当前位置: 首页 > news >正文

Spring 配置绑定原理分析

Spring 配置绑定原理分析

前言

Spring 应用中存在诸多配置,有的是系统配置,有的命令行启动参数配置,有的是yaml配置,有的是分布式配置中心配置,但对使用者而言总是可以通过@ConfigurationProperties将它关联到一个JavaBean当中或者使用@Value绑定,使得获取这这些来自不同地方的配置就像获取一个对象属性那么简单,那么它是如何来完成这个工作的呢?

结构层次

AbstractEnvironment是Spring环境的抽象实体,它存在一个MutablePropertySources类型(意为可变的配置源)的变量 propertySources,后者维护了系统中所有的配置源,系统环境变量可以是一个配置源,启动参数可以是一个配置源,application.yaml可以是一个配置源,甚至我们可以自定义一个配置源

image-20241106210028035

数据源之间的冲突

我们定义了这么一个配置,我们指定了hk.name的默认值

@Data
@Configuration
@ConfigurationProperties("hk")
public class HkConfig {private String name  = "default";
}

我们在application.yaml做出如下配置

hk:name: huakai

然后在启动参数也做出配置

--hk.name=hualuo

那么最终我们获取到的hk.name应该是哪一个呢?

答案是这是一个约定,原则是通常遵循着"靠近应用优先原则",通常情况下,

优先级顺序一般如下(从高到低):

  1. 命令行参数
  2. application.propertiesapplication.yml
  3. 操作系统环境变量
  4. JNDI 属性
  5. JVM 系统属性
  6. @PropertySource 注解配置的属性文件
  7. 默认值(在代码中指定的默认值)

实现上是如何做的呢

我们可以看到MutablePropertySources自身维护着一个List<PropertySource<?>>而配置的优先级别决定于配置源在list中的位置,配置源所处的位置越靠前那么它的优先级越高,后者又是因为Spring的策略是遍历配置源如果找到立即返回,这在Binder的实现中可见一斑

private ConfigurationProperty findProperty(ConfigurationPropertyName name, Context context) {if (name.isEmpty()) {return null;}for (ConfigurationPropertySource source : context.getSources()) {ConfigurationProperty property = source.getConfigurationProperty(name);if (property != null) {return property;}}return null;
}

MutablePropertySources

这个可变的数据源,提供了一些添加数据源的方法,包括以下两个

addFirst()

​ 这意味着被添加的数据源将最高的优先级

addLast()

​ 这意味着被添加的数据源将最低的优先级

	public void addFirst(PropertySource<?> propertySource) {synchronized (this.propertySourceList) {removeIfPresent(propertySource);this.propertySourceList.add(0, propertySource);}}public void addLast(PropertySource<?> propertySource) {synchronized (this.propertySourceList) {removeIfPresent(propertySource);this.propertySourceList.add(propertySource);}}

自定义PropertySources

我们定义一个指定的数据源并且期望它的优先级最高

CustomPropertySource

package com.huakai.springenv.config;import org.springframework.core.env.PropertySource;
import java.util.HashMap;
import java.util.Map;public class CustomPropertySource extends PropertySource<Object> {private final Map<String, String> properties = new HashMap<>();public CustomPropertySource(String name) {super(name);// 在此添加您自定义的属性properties.put("hk.name", "customValue");}@Overridepublic Object getProperty(String name) {return properties.get(name);}
}

CustomPropertySourcePostProcessor

package com.huakai.springenv.config;import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;public class CustomPropertySourcePostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {MutablePropertySources propertySources = environment.getPropertySources();CustomPropertySource customPropertySource = new CustomPropertySource("customPropertySource");propertySources.addFirst(customPropertySource);}
}

spring.factories

org.springframework.boot.env.EnvironmentPostProcessor=com.huakai.springenv.config.CustomPropertySourcePostProcessor

ps:EnvironmentPostProcessor 在 Spring 应用上下文初始化之前就被加载和执行所以只能通过该方式配置

测试

@Resource
private HkConfig hkConfig;@RequestMapping("testGetConfig")
public String test2() {return hkConfig.getName();
}

image-20241106214520252


http://www.mrgr.cn/news/67186.html

相关文章:

  • VBA06-组件
  • 华为HD集群重启NAMENODE实例操作步骤
  • 2024 - pathlinkR:差异分析 + 蛋白互作 + 功能富集网络可视化
  • 写文件回前端进行下载,报错:原因:CORS 头缺少 ‘Access-Control-Allow-Origin‘)
  • 融合智能化和信息化的技术的智慧地产开源了。
  • Centos 7离线安装ntpd服务
  • 复合查询【MySQL】
  • 蓝牙协议的前世今生
  • 复现LLM——带你从零认识自注意力
  • L6.【LeetCode笔记】合并两个有序链表
  • 【机器学习】k最近邻分类
  • Android中Activity启动的模式
  • python验证码滑块图像识别
  • 基于SSM的校园美食交流系统【附源码】
  • 法语vous voulez
  • LoRA:大型语言模型(LLMs)的低秩适应;低秩调整、矩阵的低秩与高秩
  • 算法——双指针
  • C++builder中的人工智能(7)如何在C++中开发特别的AI激活函数?
  • Redis的内存淘汰机制
  • MySQL 批量删除海量数据的几种方法
  • 【算法】(Python)贪心算法
  • 解决return code from pthread_create() is 22报错问题
  • 数据结构 ——— 链式二叉树oj题:相同的树
  • mqtt 传递和推送 温湿度计消息 js
  • 盘点10款录音转文字工具,帮你开启高效记录。
  • 架构零散知识点