【Spring Boot 源码学习】初识 ConfigurableEnvironment
《Spring Boot 源码学习系列》

初识 ConfigurableEnvironment
- 一、引言
- 二、主要内容
- 2.1 Environment
- 2.1.1 配置文件(profiles)
- 2.1.2 属性(properties)
- 2.2 ConfigurablePropertyResolver
- 2.2.1 属性类型转换配置
- 2.2.2 占位符配置
- 2.2.3 值分隔符配置
- 2.2.4 必需属性验证配置
- 2.3 ConfigurableEnvironment
- 2.3.1 接口方法
- 2.3.2 具体实现
- 三、总结
一、引言
上篇博文,Huazie 带大家深入分析下 ApplicationArguments 接口及其默认实现。在初始化完 ApplicationArguments 之后,Spring Boot 就开始通过 prepareEnvironment 方法对 ConfigurableEnvironment 对象进行初始化操作。在介绍 ConfigurableEnvironment 的初始化之前,我们有必要先认识一下 ConfigurableEnvironment 接口。

二、主要内容
注意: 以下涉及 Spring Boot 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。
下面贴出 ConfigurableEnvironment 的源码:
public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {void setActiveProfiles(String... profiles);void addActiveProfile(String profile);void setDefaultProfiles(String... profiles);MutablePropertySources getPropertySources();Map<String, Object> getSystemProperties();Map<String, Object> getSystemEnvironment();void merge(ConfigurableEnvironment parent);
}
从上述源码,可以看出 ConfigurableEnvironment 接口继承了 Environment 和 ConfigurablePropertyResolver 接口,它们其实最终都继承自 PropertyResolver 接口。
2.1 Environment

org.springframework.core.env.Environment 表示当前应用程序在其中运行的环境。它模拟了应用程序环境的两个关键方面:
2.1.1 配置文件(profiles)
Profile 是一个命名的、逻辑上的 bean 定义组,这些定义只有在给定的配置文件处于活动状态时才会被注册到容器中。通过 Environment 可以确定哪些配置文件(如果有)当前是活动的,以及哪些配置文件(如果有)应该默认是活动的。可以使用 @Profile 注解来指定 bean 应该在哪个配置文件下被注册。
2.1.2 属性(properties)
属性有各种来源,如属性文件、JVM 系统属性、系统环境变量、JNDI、servlet 上下文参数、临时的 Properties 对象、Map 等。Environment 对象为用户提供了一个方便的服务接口,用于配置属性源并从这些源中解析属性。通过 Environment,可以方便地访问和解析这些属性,而无需直接操作这些源。
此外,Environment 接口还继承了 PropertyResolver 接口【用于根据任何底层源解析属性的接口】,这意味着它还提供了与属性访问相关的功能。
2.2 ConfigurablePropertyResolver

org.springframework.core.env.ConfigurablePropertyResolver 也继承了 PropertyResolver 接口,并在其基础上增加了更多的配置选项:
2.2.1 属性类型转换配置
ConfigurablePropertyResolver 提供了基于 org.springframework.core.convert.ConversionService 的属性类型转换功能。ConversionService 是 Spring 中用于类型转换的接口,它允许将一种类型的对象转换为另一种类型的对象。
与之关联的方法如下:
getConversionService(): 获取当前用于类型转换的ConfigurableConversionService实例。setConversionService(ConfigurableConversionService conversionService): 设置用于类型转换的ConfigurableConversionService实例。这允许用户自定义类型转换的逻辑,以满足特定的应用程序需求。
2.2.2 占位符配置
ConfigurablePropertyResolver 允许开发者配置占位符的前缀和后缀。默认情况下,前缀是 ${,后缀是 }。占位符的值本身也可以包含其他占位符,形成嵌套占位符,ConfigurablePropertyResolver 支持嵌套占位符的解析。
与之相关的方法如下:
setPlaceholderPrefix(String placeholderPrefix): 设置占位符的前缀。在解析属性时,这些前缀将被用来识别需要替换的占位符。setPlaceholderSuffix(String placeholderSuffix): 设置占位符的后缀。与前缀一起,它们定义了占位符的完整格式。setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders): 设置是否忽略无法解析的嵌套占位符。如果设置为true,则当遇到无法解析的嵌套占位符时,解析器将不会抛出异常,而是继续执行。
2.2.3 值分隔符配置
值分隔符是指在解析属性值时,用于分隔占位符与其关联默认值的字符设置。
比如,在配置文件中有这样的属性值:${propertyName:defaultValue}。
在这里 propertyName 是占位符,而 defaultValue 是在 propertyName 无法解析时使用的默认值。那显然在上述示例中,: 就是 值分隔符。
与之相关的方法如下:
setValueSeparator(@Nullable String valueSeparator): 设置值分隔符。在某些情况下,属性值可能包含多个值,这些值由分隔符分隔。此方法允许用户指定分隔符。
2.2.4 必需属性验证配置
必需属性验证配置是 Spring 框架中用于确保应用程序配置中包含某些关键属性的一种机制。
与之相关的方法如下:
setRequiredProperties(String... requiredProperties): 设置必需的属性。这些属性必须在解析过程中存在,否则验证将失败。validateRequiredProperties() throws MissingRequiredPropertiesException: 验证是否所有必需的属性都已设置。如果任何必需属性缺失,此方法将抛出MissingRequiredPropertiesException异常。
2.3 ConfigurableEnvironment
了解了 Environment 和 ConfigurablePropertyResolver,我们再来看看 ConfigurableEnvironment 。
2.3.1 接口方法
ConfigurableEnvironment 代表了一个可配置的环境,其定义了如下的方法:
setActiveProfiles(String... profiles):设置当前激活的Profile组集合。在Spring 中,Profile允许用户根据特定的环境(如开发、测试、生产)加载不同的配置。通过传递一个或多个Profile名称作为参数,你可以激活这些Profile。addActiveProfile(String profile):向当前激活的Profile组集合中添加一个Profile组。setDefaultProfiles(String... profiles):设置默认激活的Profile组集合。激活的Profile组集合为空时,会默认实用默认的Profile组集合。getPropertySources():返回当前环境的MutablePropertySources对象。PropertySources是一个包含多个PropertySource的列表,每个PropertySource都可以提供属性。MutablePropertySources允许你添加、替换或删除PropertySource。getSystemProperties():返回 Java 系统属性的映射。这些属性是 JVM 启动时通过-D参数或在代码中使用System.setProperty(key, value)进行设置。getSystemEnvironment():返回操作系统环境变量的映射。这些变量通常包含关于系统配置和运行时的信息。merge(ConfigurableEnvironment parent):将父ConfigurableEnvironment的属性源合并到当前环境中。合并时,父环境的属性源将添加到当前环境的属性源列表的开头,从而允许它们覆盖当前环境的任何同名属性。
2.3.2 具体实现
org.springframework.core.env.AbstractEnvironment 是一个抽象类,实现了 ConfigurableEnvironment 接口,为环境配置(如属性源和 Profile 文件管理)提供了基本的支持。
org.springframework.core.env.StandardEnvironment 继承自 AbstractEnvironment,应用于非 Web 环境。它是 Spring 中默认的环境配置类,负责读取系统属性、环境变量以及配置文件中的配置信息,并将其封装在一个 PropertySources 对象中供 Spring 应用程序使用。
org.springframework.web.context.support.StandardServletEnvironment 继承自 StandardEnvironment,它是基于 Servlet 的 Web 应用程序要使用的 Environment 实现。所有基于 Servlet 的 Web 相关的 ApplicationContext 类都会默认初始化一个实例。提供 ServletConfig、ServletContext 和基于 JNDI 的 PropertySource 实例。在初始化过程中,会根据 ServletContext 和 ServletConfig 的可用性来初始化和配置属性源。通过 customizePropertySources() 方法,可以自定义属性源的添加顺序和配置方式。
org.springframework.mock.env.MockEnvironment 继承自 AbstractEnvironment,它用于测试目的,可以模拟环境变量和系统属性的值。
三、总结
本篇博文 Huazie 同大家一起了解了 ConfigurableEnvironment 接口和其父接口,这些对于后续理解 ConfigurableEnvironment 的初始化操作至关重要。接下来的博文将会继续聚焦 Spring Boot 启动运行阶段,敬请期待!!!
相关文章:
【Spring Boot 源码学习】初识 ConfigurableEnvironment
《Spring Boot 源码学习系列》 初识 ConfigurableEnvironment 一、引言二、主要内容2.1 Environment2.1.1 配置文件(profiles)2.1.2 属性(properties) 2.2 ConfigurablePropertyResolver2.2.1 属性类型转换配置2.2.2 占位符配置2.…...
开关电源中强制连续FCCM模式与轻载高效PSM,PFM模式优缺点对比笔记
文章目录 前言一、连续FCCM模式优点:缺点: 二,轻载高效PSM,PFM优点:缺点: 总结 前言 今天我们来学习下开关电源中,强制连续FCCM模式与轻载高效PSM,PFM模式优缺点对比 一、连续FCCM模式 优点: …...
5分钟教你用AI把老照片动起来,别再去花49块9的冤枉钱了
文章目录 需要的工具 最近,AI视频在各大平台上,又火了。 只是火的形式,变成了将老照片动起来,打情感牌,或者做很多经典电视剧的再整活。 直接把可灵的生成时间,从以前的4分钟,生生的干成了20分钟…...
Ruby 环境变量
Ruby 环境变量 概述 环境变量在编程中扮演着重要的角色,尤其是在Ruby这样的动态编程语言中。它们是操作系统用来存储有关其操作环境的信息的变量,可以在程序运行时影响其行为。Ruby程序可以通过环境变量来获取配置信息、系统细节或用户特定的设置。本文将深入探讨Ruby中环境…...
BPF:BCC工具 funccount 统计内核函数调用(内核函数、跟踪点USDT探针)认知
写在前面 博文内容涉及BCC工具 funccount 认知funccount 可以帮助用户追踪和分析Linux系统上特定函数、系统探针或USDT探针的运行次数。这对于性能分析、故障排查和系统优化等场景非常有用。理解不足小伙伴帮忙指正 😃,生活加油 不必太纠结于当下,也不必…...
DPO算法推导
DPO 核心思想:直接使用偏好数据进行策略优化,省去 reward 模型策略优化。 技术背景知识: 首先给定prompt x,生成两个答案 ( y 1 , y 2 ) Π S F T ( y ∣ x ) (y_1,y_2)~\Pi^{SFT}(y|x) (y1,y2) ΠSFT(y∣x) ,并通…...
Qt源码分析:窗体绘制与响应
作为一套开源跨平台的UI代码库,窗体绘制与响应自然是最为基本的功能。在前面的博文中,已就Qt中的元对象系统(反射机制)、事件循环等基础内容进行了分析,并捎带阐述了窗体响应相关的内容。因此,本文着重分析Qt中窗体绘制相关的内容…...
docker 安装 禅道
docker pull hub.zentao.net/app/zentao:20.1.1 sudo docker network create --subnet172.172.172.0/24 zentaonet 使用 8087端口号访问 使用禅道mysql 映射到3307 sudo docker run \ --name zentao2 \ -p 8087:80 \ -p 3307:3306 \ --networkzentaonet \ --ip 172.172.172.…...
【简要说说】make 增量编译的原理
make 增量编译的原理 make是一个工具,它可以根据依赖关系和时间戳来自动执行编译命令。 当您修改了源代码文件后,make会检查它们的修改时间是否比目标文件(如可执行文件或目标文件)新,如果是,就会重新编译…...
DETRs Beat YOLOs on Real-time Object Detection论文翻译
cvpr 2024 论文名称 DETRs在实时目标检测上击败YOLO 地址 https://arxiv.longhoe.net/abs/2304.08069 代码 https://github.com/lyuwenyu/RT-DETR 目录 摘要 1介绍 2.相关工作 2.1实时目标探测器 2.2.端到端物体探测器 3.检测器的端到端速度 3.1.NMS分析 3.2.端到端速度…...
SpringBoot 多数据源配置
目录 一. 引入maven依赖包 二. 配置yml 三、创建 xml 分组文件 四、切换数据源 一. 引入maven依赖包 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.6.1&…...
RK3568驱动指南|第十六篇 SPI-第192章 mcp2515驱动编写:完善write和read函数
瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…...
#BI建模与数仓建模有什么区别?指标体系由谁来搭建?
问题1: 指标体系是我们数仓来搭建还是分析师来做,如何去推动? 问题2:BI建模与数仓建模有什么区别? 指标体系要想做好,其实是分两块内容的,一块是顶层设计阶段,业务指标体系的搭建&am…...
如何用Python实现三维可视化?
Python拥有很多优秀的三维图像可视化工具,主要基于图形处理库WebGL、OpenGL或者VTK。 这些工具主要用于大规模空间标量数据、向量场数据、张量场数据等等的可视化,实际运用场景主要在海洋大气建模、飞机模型设计、桥梁设计、电磁场分析等等。 本文简单…...
chrome.storage.local.set 未生效
之前chrome.storage.local.set 和 get 一直不起作用 使用以下代码运行成功。 chrome.storage.local.set({ pageState: "main" }).then(() > {console.log("Value is set");});chrome.storage.local.get(["pageState"]).then((result) > …...
泛微开发修炼之旅--30 linux-Ecology服务器运维脚本
文章链接:30 linux-ecology服务器运维脚本...
LeetCode 全排列
思路:这是一道暴力搜索问题,我们需要列出答案的所有可能组合。 题目给我们一个数组,我们很容易想到的做法是将数组中的元素进行排列,如何区分已选中和未选中的元素,容易想到的是建立一个标记数组,已经选中的…...
python实现支付宝异步回调验签
说明 python实现支付宝异步回调验签,示例中使用Django框架。 此方案使用了支付宝的pythonSDK,请一定装最新版本的,支付宝官网文档不知道多久没更新了,之前的版本pip安装会报一些c库不存在的错误; pip install alipay-…...
注意!Vue.js 或 Nuxt.js 中请停止使用.value
大家好,我是CodeQi! 一位热衷于技术分享的码仔。 当您在代码中使用.value时,必须每次都检查变量是否存在并且是引用。 这可能很麻烦,因为在运行时使用.value可能会导致错误。然而,有一个简单的解决方法,即使用unref()而不是.value。 unref()会检查变量是否是引用,并自…...
Java:JDK、JRE和JVM 三者关系
文章目录 一、JDK是什么二、JRE是什么三、JDK、JRE和JVM的关系 一、JDK是什么 JDK(Java Development Kit):Java开发工具包 JRE:Java运行时环境开发工具:javac(编译工具)、java(运行…...
ViGEmBus虚拟手柄驱动全栈技术指南:从内核原理到游戏控制革新
ViGEmBus虚拟手柄驱动全栈技术指南:从内核原理到游戏控制革新 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 一、认知虚拟手柄技术:…...
消防给水系统控制:西门子 S7 - 200 与昆仑通态触摸屏的奇妙组合
消防给水系统控制,西门子S7-200,昆仑通态触摸屏YH25 1.采用西门子S7-200PLC,CPU226EM223数字量模块EM231模拟量模块。 2.昆仑通态MCGS触摸屏及软件,可自行转换新版MCGSPRO程序。 3.两水泵一用二备和二用一备可切换,故障…...
计算机毕业设计springboot基于的游戏交易平台 基于SpringBoot的虚拟资产流通服务平台的设计与实现 基于SpringBoot架构的网络游戏账号及道具交易系统的设计与实现
计算机毕业设计springboot基于的游戏交易平台(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着互联网技术的飞速发展和网络游戏产业的蓬勃兴起,虚拟资产交易已成为…...
# 发散创新:基于群体智能的Python蚁群算法优化路径规划实战在人工智能快速演进的时代,**群体智能(Swarm Int
发散创新:基于群体智能的Python蚁群算法优化路径规划实战 在人工智能快速演进的时代,群体智能(Swarm Intelligence) 作为一类受自然界生物行为启发的计算范式,正逐渐成为解决复杂优化问题的重要工具。本文聚焦于蚁群算…...
GPIO的输出输入方式总结
GPIO的四种输入方式GPIO的四种输出方式...
计算机毕业设计springboot月子中心健康管理系统 基于SpringBoot的母婴护理中心智能管理平台 产后康复中心信息化服务系统
计算机毕业设计springboot月子中心健康管理系统7639p9(配套有源码 程序 mysql数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联xi 可分享随着国家三胎政策的放开和居民生活水平的提升,现代家庭对产后护理服务的专业化、…...
IOMMU性能调优全攻略:从基础原理到实战技巧
IOMMU性能调优全攻略:从基础原理到实战技巧 在数据中心和云计算环境中,IOMMU(输入输出内存管理单元)作为硬件辅助虚拟化的关键技术组件,其性能表现直接影响着整个系统的吞吐量和延迟。对于需要处理高并发I/O负载的场景…...
数字中国新引擎:产业经济大脑的全景式解构与深度洞察(PPT)
“中国经济高质量发展的核心命题,已从‘有没有’转向‘好不好’。而要回答‘好不好’,就必须构建一套能看清、看准、看远的‘经济慧眼’。”在数字经济成为国家战略主战场的今天,地方政府正面临着前所未有的治理挑战:宏观政策如何…...
Qwen3.5-4B-Claude-Opus应用场景:企业内训材料自动提炼+考试题生成实践
Qwen3.5-4B-Claude-Opus应用场景:企业内训材料自动提炼考试题生成实践 1. 企业培训面临的挑战 现代企业培训部门常常面临两大痛点:一是海量培训材料的整理提炼工作耗时费力,二是培训效果评估缺乏科学高效的考核手段。传统人工处理方式存在以…...
破局B站音频提取难题:BilibiliDown革新性解决方案全解析
破局B站音频提取难题:BilibiliDown革新性解决方案全解析 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors…...
