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.xdnf.cn/news/10504.html

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

相关文章

Hadoop生态圈框架部署(五)- Zookeeper完全分布式部署

文章目录 前言一、Zookeeper完全分布式部署&#xff08;手动部署&#xff09;1. 下载Zookeeper2. 上传安装包2. 解压zookeeper安装包3. 配置zookeeper配置文件3.1 创建 zoo.cfg 配置文件3.2 修改 zoo.cfg 配置文件3.3 创建数据持久化目录并创建myid文件 4. 虚拟机hadoop2安装并…

HarmonyOS Next 实战卡片开发 03

HarmonyOS Next 实战卡片开发 03 在前面两张&#xff0c;我们基本掌握了卡片的使用流程&#xff0c;本章节就通过一个实战来加强对卡片使用的理解。 要完成的案例 新建项目和新建服务卡片 设置沉浸式 entry/src/main/ets/entryability/EntryAbility.ets 首页显示轮播图数据 1…

基于 PyTorch 从零手搓一个GPT Transformer 对话大模型

一、从零手实现 GPT Transformer 模型架构 近年来&#xff0c;大模型的发展势头迅猛&#xff0c;成为了人工智能领域的研究热点。大模型以其强大的语言理解和生成能力&#xff0c;在自然语言处理、机器翻译、文本生成等多个领域取得了显著的成果。但这些都离不开其背后的核心架…

三、整数规划

整数规划 建立逻辑变量来整合多个方案。如0-1变量&#xff08;要说明0和1分别表示什么&#xff09;见P79求解纯整数规划的分支定界法&#xff1a; 求解整数规划的松弛问题的最优解若松弛问题的最优解满足整数要求&#xff0c;则得到整数规划的最优解&#xff0c;否则转下一步任…

Docker了解

Docker是一种容器化技术&#xff0c;它可以将应用程序和其依赖项打包到一个独立的、可移植的容器中&#xff0c;以便在不同的环境中运行。Docker基于Linux操作系统的容器化技术&#xff0c;可以提供更轻量、更快速、更灵活、更一致的应用部署和管理方式。 Docker的基本概念包括…

stm32以太网接口:MII和RMII

前言 使用stm32和lwip进行网络通信开发时&#xff0c;实现结构如下&#xff1a; 而MII和RMII就是stm32与PHY芯片之间的通信接口&#xff0c;类似于I2C、UART等。 stm32以太网模块有专用的DMA控制器&#xff0c;通过AHB接口将以太网内核和存储器相连。 数据发送时&#xff0c;…

【GESP】C++一级真题练习(202312)luogu-B3921,小杨的考试

GESP一级真题练习。为2023年12月一级认证真题。逻辑计算问题。 题目题解详见&#xff1a;【GESP】C一级真题练习(202312)luogu-B3921&#xff0c;小杨的考试 | OneCoder 【GESP】C一级真题练习(202312)luogu-B3921&#xff0c;小杨的考试 | OneCoderGESP一级真题练习。为2023…

【java】通过<类与对象> 引入-> 链表

目录 链表 碎片化&#xff1a; 内存碎片产生的原因 如何避免内存碎片&#xff1f; 链表类型 单链表 双链表 单循环链表 双循环链表 java是如何创建链表的&#xff1f; 类与对象 类是什么&#xff1f; 什么是对象&#xff1f; 构建链表 头指针 简画内存图&#…

微软开源5级Agent框架,复杂任务就这么被解决了~

微软又来卷Agent&#xff0c;开源了解决复杂任务的通用Multi-Agent框架Magentic-One&#xff0c;它旨在解决开放性的网络和基于文件的任务&#xff0c;跨越各种领域&#xff0c;如操作网络浏览器、导航本地文件、编写和执行Python代码、做市场调研、写论文等等。 Magentic-One…

矩阵中的路径(dfs)-acwing

题目 23. 矩阵中的路径 - AcWing题库 代码 class Solution { public://以每一个坐标作为dfs起点bool hasPath(vector<vector<char>>& matrix, string str) {for (int i 0; i < matrix.size(); i )for (int j 0; j < matrix[i].size(); j )if (dfs(…

欢迎 Stable Diffusion 3.5 Large 加入 Diffusers

作为Stable Diffusion 3的改进版本&#xff0c;Stable Diffusion 3.5 如今已在 Hugging Face Hub 中可用&#xff0c;并可以直接使用 &#x1f9e8; Diffusers 中的代码运行。 https://hf.co/blog/sd3 本次发布包含两套模型参数: https://hf.co/collections/stabilityai/stable…

Docker入门系列——DockerFile的使用

前面了解了Docker的基本概念&#xff0c;今天来认识一下DockerFile。 Dockerfile 是一个文本文件&#xff0c;包含一系列指令来组装 Docker 镜像。每个指令执行一个特定动作&#xff0c;例如安装包、复制文件或定义启动命令。正确使用 Dockerfile 指令对于构建高效容器至关重要…

2-146 基于matlab的双摆杆系统建模分析

基于matlab的双摆杆系统建模分析。连接方式为铰接&#xff0c;两杆均视为均质杆&#xff0c;动态输出摆杆末端轨迹。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-146 基于matlab的双摆杆系统建模分析

基于java+SpringBoot+Vue的美发门店管理系统设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven mysql5.7或8.0等等组成&#x…

基于vue框架的的楼盘销售管理系统6n60a(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 用户,房源类型,员工,房源信息,购房预订,购房合同 开题报告内容 基于Vue框架的楼盘销售管理系统开题报告 一、研究背景 随着房地产市场的蓬勃发展&#xff0c;楼盘销售行业的竞争日益激烈。传统的销售管理方式依赖于人工记录和纸质文档&#xff0c;效率低下…

值得一看的小模型技术全面总结及RAG文档处理及切分小模型工具

、 本文还是来看看RAG&#xff0c;不过是从另一个角度&#xff0c;从小模型(其实这个小不太好说&#xff0c;7B或者以下&#xff1f;)角度&#xff1b; 因此&#xff0c;讲两件事&#xff0c;一个是回顾下小模型&#xff0c;推荐一个写的很好的小模型进展技术总结综述&#xf…

大模型好书案例——《BERT基础教程:Transformer大模型实战》(附PDF)

《BERT基础教程&#xff1a;Transformer大模型实战》是一本关于自然语言处理&#xff08;NLP&#xff09;的书籍&#xff0c;专注于谷歌公司开发的BERT模型。这本书由印度作者苏达哈尔桑拉维昌迪兰&#xff08;Sudharsan Ravichandiran&#xff09;撰写&#xff0c;周参翻译。 …

关于Markdown的一点疑问,为什么很多人说markdown比word好用?

markdown和word压根不是一类工具&#xff0c;不存在谁比谁好&#xff0c;只是应用场景不一样。 你写博客、写readme肯定得markdown&#xff0c;但写合同、写简历肯定word更合适。 markdown和word类似邮箱和微信的关系&#xff0c;这两者都可以通信&#xff0c;但微信因为功能…

ASR 点屏

ASR翱捷科技 ASR kernel 5.10 android14 ASR EVB平台 以gc7202 jd9365这两块屏为例 新旧DTBO点屏配置是有区别的,主要差异是体现在 asr\kernel\u-boot\board\asr\dove\dovc.c这个文件上 旧DTBO: 新DTBO: 目前我们的代码已经合入新的DTBO 以前在没有合入asr新的DTBO时点亮…

Ubuntu24.04网络异常与应对方案记录

PS: 参加过408改卷的ZJU ghsongzju.edu.cn 开启嘲讽: 你们知道408有多简单吗&#xff0c;操作系统真实水平自己知道就行&#xff5e;&#xff5e; Requested credits of master in UWSC30&#xff0c;in ZJU24&#xff0c;domestic master is too simple dmesg dmesg 是一个用…