【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(运行…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...