Spring源码:Spring运行环境Environment
Spring运行环境
Spring在创建容器时,会创建Environment环境对象,用于保存spring应用程序的运行环境相关的信息。在创建环境时,需要创建属性源属性解析器,会解析属性值中的占位符,并进行替换。
创建环境时,会通过System.getProperties()获取JVM系统属性,会通过System.getenv()获取JVM环境属性。
Environment在Spring中的使用
spring在创建容器时需要指定需要加载配置文件路径,在加载配置文件路径时,需要解析字符串中的占位符。解析占位符时,需要环境信息,此时会创建一个标准的spring运行环境,即创建StandardEnvironment对象。
1、调用setConfigLocations方法给spring设置需要加载的配置文件的路径,源码如下:
// 将配置文件的路径放到configLocations 字符串数组中
public void setConfigLocations(@Nullable String... locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");// 设置了几个配置文件,就创一个多长的字符串数组,用来存放配置文件的路径this.configLocations = new String[locations.length];for (int i = 0; i < locations.length; i++) {//解析路径,将解析的路径存放到字符串数组中this.configLocations[i] = resolvePath(locations[i]).trim();}}else {this.configLocations = null;}
}
2、调用resolvePath方法解析配置文件路径中的占位符,源码如下:
// 解析给定的路径,必要时用相应的环境属性值替换占位符。应用于配置位置。
protected String resolvePath(String path) {// 获取环境,解决所需的占位符return getEnvironment().resolveRequiredPlaceholders(path);
}
3、调用getEnvironment方法获取环境信息,如果没有指定spring的环境信息,通过createEnvironment获取默认的环境,也就是spring的标准环境。getEnvironment方法源码如下:
// 获取spring的环境信息,如果没有指定,获取到的时默认的环境
@Override
public ConfigurableEnvironment getEnvironment() {if (this.environment == null) {this.environment = createEnvironment();}return this.environment;
}
4、调用createEnvironment方法获取默认的环境(spring的标准环境),使用StandardEnvironment无参构造创建对象。源码如下:
// 获取默认的环境
protected ConfigurableEnvironment createEnvironment() {return new StandardEnvironment();
}
Spring的标准环境StandardEnvironment
Spring的标准环境StandardEnvironment适合在非web应用程序中使用。
在AbstractApplicationContext类的createEnvironment方法中会调用StandardEnvironment的无参构造方法创建环境对象。
1、调用StandardEnvironment的无参构造方法,该方法中没有任何逻辑处理,源码如下:
public StandardEnvironment() {}
2、StandardEnvironment类是AbstractEnvironment抽象类的子类,因此使用StandardEnvironment的无参构造创建对象时会调用父类AbstractEnvironment的无参构造方法。AbstractEnvironment在下文中有描述。
3、重写AbstractEnvironment类中的customizePropertySources方法,用于设置属性源,该方法通过父类进行回调。
该方法会获取JVM系统属性和环境属性并设置到MutablePropertySources类中存放属性源的CopyOnWriteArrayList中。
1)JVM系统属性通过System.getProperties()获取;
2)环境属性通过System.getenv()获取。
StandardEnvironment类中customizePropertySources方法源码如下:
// 设置属性源,JVM系统属性中的属性将优先于环境属性中的属性。
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {/*** 1、MutablePropertySources类中使用CopyOnWriteArrayList存储属性源,集合中存储PropertySource的子类* 2、PropertiesPropertySource是PropertySource的子类,PropertySource类中有三个成员变量* 1)logger:日志对象* 2)name:用来保存属性源名称* 3)source:用来保存属性源中的属性*/// getSystemProperties():通过System.getProperties()获取JVM属性键值对,并转成MappropertySources.addLast(new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));// getSystemEnvironment():通过System.getenv()获取环境属性键值对,并撰成MappropertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
}
4、StandardEnvironment类中设置了两个静态常量:
1)systemEnvironment:以系统环境为属性源
2)systemProperties:以JVM系统属性为属性源
/** System environment property source name: {@value}.* 系统环境属性源名:{@value}。 */
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";/** JVM system properties property source name: {@value}.* JVM系统属性属性源名称:{@value}。*/
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
Spring的抽象环境AbstractEnvironment
StandardEnvironment类是AbstractEnvironment抽象类的子类,因此使用StandardEnvironment的无参构造创建对象时会调用父类AbstractEnvironment的无参构造方法。
1、AbstractEnvironment的无参构造方法,该方法会调用AbstractEnvironment的有参构造方法,源码如下:
public AbstractEnvironment() {this(new MutablePropertySources());
}
2、AbstractEnvironment的有参构造
该方法的主要做三件事:
1)给成员变量赋值
2)创建属性源属性解析器
3)调用子类重写的customizePropertySources方法(方法回调)。虽然方法回调在成员变量的赋值之后,但由于是引用传递,所以通过成员属性可以获取到改变之后的值。
// 使用了模板方法设计模式。
// 给成员变量赋值,并调用子类重写的方法,对propertySources进行操作。
protected AbstractEnvironment(MutablePropertySources propertySources) {// 给全局变量 可变属性源 赋值this.propertySources = propertySources;// 创建属性解析器:PropertySourcesPropertyResolver 属性源属性解析器this.propertyResolver = createPropertyResolver(propertySources);// 自定义属性源,此处回调子类重写的方法。子类通过重写该方法可以操作propertySources。spring标准环境StandardEnvironment重写了该方法customizePropertySources(propertySources);
}
3、调用createPropertyResolver创建属性解析器,用于解析属性值中的占位符并进行替换。
// 在创建环境时,需要创建属性解析器
protected ConfigurablePropertyResolver createPropertyResolver(MutablePropertySources propertySources) {return new PropertySourcesPropertyResolver(propertySources);
}
4、AbstractEnvironment的成员属性
// 指示Spring忽略系统环境变量,默认值为"false"。
// false表示不会忽略系统环境变量,此时getSystemEnvironment方法会调用System.getenv()获取环境属性
// true表示会忽略系统的环境变量,此时getSystemEnvironment方法会返回一个空的Map
public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";// 指定系统启动时使用哪些配置文件,可以使用逗号隔开
public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";// 指定系统启动时使用默认的配置文件,可以使用逗号隔开
public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";// 保留的默认的配置文件的名称,如果没有显式设置默认配置文件名称,也没有显式设置活动配置文件名称,则默认情况下该配置文件将自动激活。
protected static final String RESERVED_DEFAULT_PROFILE_NAME = "default";// 日志对象
protected final Log logger = LogFactory.getLog(getClass());//系统启动时使用的配置文件
private final Set<String> activeProfiles = new LinkedHashSet<>();// 默认配置文件
private final Set<String> defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles());// 可变属性源,使用该成员变量保存属性源及通过该属性源获取的属性
private final MutablePropertySources propertySources;// 可配置的属性解析器
private final ConfigurablePropertyResolver propertyResolver;
相关文章:
Spring源码:Spring运行环境Environment
Spring运行环境 Spring在创建容器时,会创建Environment环境对象,用于保存spring应用程序的运行环境相关的信息。在创建环境时,需要创建属性源属性解析器,会解析属性值中的占位符,并进行替换。 创建环境时,…...
SpringBoot使用PropertiesLauncher加载外部jar包
Springboot启动入口源码 默认是org.springframework.boot.loader.JarLauncher <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-loader</artifactId> </dependency>启用SpringBoot的PropertiesLaunche…...
骑行 - 出发前如何准备
现在路上经常见到武装完备的自行车骑手,一般是公路车,出来骑个几十公里是很正常的。出来骑车是个很快乐的事,但出发前还是有许多需要准备的。 最开始,要评估一下天气情况,出车前看下外面天气情况以及预报。提前几天计划…...
ssm员工管理系统
ssm员工管理系统 java员工管理系统 员工管理系统 运行环境: JAVA版本:JDK1.8 IDE类型:IDEA、Eclipse都可运行 数据库类型:MySql(8.x版本都可) 硬件环境:Windows 功能介绍: 1.用户…...
《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(16)-Fiddler如何充当第三者再识AutoResponder标签-上
1.简介 Fiddler充当第三者,主要是通过AutoResponder标签在客户端和服务端之间,Fiddler抓包,然后改包,最后发送。AutoResponder这个功能可以算的上是Fiddler最实用的功能,可以让我们修改服务器端返回的数据,…...
Yolov8新版本解读:优化点如何加入新版本,通过加入EMA注意力进行对比说明
本文目的: 最近yolov8进行了一次较大的更新,对一些优化点加在哪个位置上有些变动,因此本文主要通过具体案列进行对比和说明,以便在新版本上能够轻松上手。 老版本 ultralytics/nn 新版本更新为: modules文件夹下内容如下: 解读: 将modules.py拆分为 1.__init__.…...
NoSQL———Redis配置与优化
目录 一、关系数据库与非关系型数据库 1.1 关系型数据库 1.2 非关系型数据库 1.3 关系型数据库和非关系型数据库区别 1.3.1 非关系型数据库产生背景 二、Redis简介 2.1 redis优点: 三、Redis 安装部署 四、Redis 命令工具 4.1 redis-cli 命令行工具 …...
js,瀑布流
该方法仅满足,元素等宽,高度一般不同的瀑布流布局 计算元素宽度与浏览器宽度之比,得到布局列数;将未布局的元素依次布局至高度最小的那一列;页面滚动时继续加载数据,动态地渲染在页面上。 <div id&quo…...
“深入了解Spring Boot:从入门到精通“
标题:深入了解Spring Boot:从入门到精通 摘要:本文将介绍Spring Boot的基本概念、特性和优势,以及如何使用Spring Boot来开发Java应用程序。通过深入学习Spring Boot的核心组件和常用功能,读者将能够熟练运用Spring B…...
记录时间计算bug getDay()的一个坑
最近在使用时间计算展示当天所在这一周的数据 不免要获取当前时间所在周 // 时间格式整理函数 function formatDate(date) {const year date.value.getFullYear(),month String(date.value.getMonth() 1).padStart(2, 0),day String(date.value.getDate()).padStart(2, 0)…...
【lesson5】linux vim介绍及使用
文章目录 vim的基本介绍vim的基本操作vim常见的命令命令模式下的命令yypnyynpuctrlrGggnG$^wbh,j,k,lddnddnddp~shiftrrnrxnx 底行模式下的命令set nuset nonuvs 源文件wq!command(命令) vim配置解决无法使用sudo问题 vim的基本介绍 首先vim是linux下的…...
【玩转Linux】Linux输入子系统简介
(꒪ꇴ꒪ ),hello我是祐言博客主页:C语言基础,Linux基础,软件配置领域博主🌍快上🚘,一起学习!送给读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!作者水平很有限,如果发现错误&#x…...
grid map学习笔记2之grid map的一些常规定义和功能包说明
文章目录 0 引言1 常规定义1.1 单层grid map1.2 多层grid map1.3 迭代器类别1.4 移动grid map的位置 2 功能包2.1 grid_map_rviz_plugin2.2 grid_map_sdf2.3 grid_map_visualization2.3.1 订阅的主题2.3.2 发布的主题 2.4 grid_map_filters 0 引言 grid map学习笔记1已成功在U…...
Python-文件操作
Python文件操作 1. 打开文件 使用open()函数打开文件,指定文件名和模式,常用模式有: r - 读取(默认)w - 写入(会先截断文件)a - 追加b - 二进制模式t - 文本模式(默认) - updating (reading and writing) f open(data.txt,r) # 打开data.txt文件用于读取2. 读取文件 f.re…...
windows中注册redis服务启动时报1067错误
注册完redis服务,打开计算机 服务时确实有redis服务存在,但是点击启动时却报1067错误,而命令行用redis-server.exe redis.windows.conf 命令却也可以启动 查看6379的端口也没有被占用(netstat -ano | findstr :6379) …...
大数据面试题:HBase的RegionServer宕机以后怎么恢复的?
面试题来源: 《大数据面试题 V4.0》 大数据面试题V3.0,523道题,679页,46w字 可回答:1)HBase一个节点宕机了怎么办;2)HBase故障恢复 参考答案: 1、HBase常见故障 导…...
ansible的脚本——playbook剧本
目录 一、playbook的组成 二、 playbook安装httpd服务 1.编写playbook剧本 2.运行playbook 三、定义、引用变量 四、 指定远程主机sudo切换用户 五、when条件判断 六、迭代 七、Templates 模块 1.先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变…...
【系统监控程序】
用python编写一个系统监控程序,需要每隔一秒钟记录系统每个进程的资源占用和整体的资源占用情况,并输出成json,保存到文本文件。 import psutil import json import timedef get_process_usage():process_list []for proc in psutil.proces…...
计算机论文中名词翻译和解释笔记
看论文中一些英文的简写不知道中文啥意思,或者一个名词不知道啥意思。 于是自己做了一个个人总结。 持续更新 目录 SoftmaxDeep Learning(深度学习)循环神经网络(Recurrent Neural Network简称 RNN)损失函数/代价函数(Loss Function)基于手绘草图的三维模型检索(Ske…...
读书笔记-《ON JAVA 中文版》-摘要20[第十九章 类型信息-1]
文章目录 第十九章 类型信息1. 为什么需要 RTTI2. Class 对象2.1 Class 对象2.2 类字面常量2.3 泛化的 Class 引用 3. 类型转换检测4. 注册工厂5. 类的等价比较6. 反射:运行时类信息7. 自我学习总结 第十九章 类型信息 RTTI(RunTime Type Information&am…...
Fast-GitHub:三步安装解决国内GitHub访问难题的终极指南
Fast-GitHub:三步安装解决国内GitHub访问难题的终极指南 【免费下载链接】Fast-GitHub 国内Github下载很慢,用上了这个插件后,下载速度嗖嗖嗖的~! 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 你是否经常因为…...
别再只盯着wx.login了!SpringBoot后端实战:用getPhoneNumber接口搞定小程序用户手机号绑定
微信小程序用户手机号绑定:SpringBoot后端深度实践指南 在当今移动互联网生态中,微信小程序已成为连接用户与服务的重要桥梁。对于需要强实名认证或直接触达用户的业务场景(如电商交易、金融服务、政务办理等),仅依赖w…...
Wand-Enhancer:零成本解锁WeMod高级功能的完整指南
Wand-Enhancer:零成本解锁WeMod高级功能的完整指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 还在为WeMod专业版的订阅费用而犹豫不决吗…...
Unity游戏开发集成MCP协议:AI助手自动化操作指南
1. 项目概述:Unity游戏开发中的MCP革命如果你是一名Unity开发者,最近可能已经注意到一个名为“CoderGamester/mcp-unity”的项目在GitHub上悄然走红。这不仅仅是一个普通的插件或工具包,它代表了一种全新的工作流范式,旨在将大型语…...
【ElevenLabs情绪模拟技术白皮书】:基于2,147小时情感语音标注数据集的11类基础情绪迁移模型验证报告
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs情绪模拟技术白皮书概述 ElevenLabs的情绪模拟技术并非简单调节音高或语速,而是基于多模态情感表征学习(Multimodal Affective Representation Learning, MARL&#x…...
量子控制中的动态校正门与SCQC几何方法
1. 量子控制中的噪声挑战与动态校正门在超导量子处理器上实现高保真度的量子门操作,最大的障碍来自环境噪声。这些噪声主要分为两类:失谐噪声(δz)和幅度噪声(ϵ)。失谐噪声源于量子比特频率的漂移…...
【仅剩217份】《Midjourney后印象派风格白皮书》V2.3——含17位艺术家专属LoRA适配建议、32组跨文化色彩映射表及实时风格强度校准工具(2024.06内部封测版)
更多请点击: https://intelliparadigm.com 第一章:后印象派风格的视觉基因与Midjourney语义解码 后印象派并非对自然的模仿,而是对色彩、结构与主观情绪的系统性重构——梵高旋转的星云、塞尚凝固的苹果、高更平面化的塔希提图腾,…...
Arduino与手机蓝牙通信:nRF8001 BLE模块硬件连接与软件配置全解析
1. 项目概述与核心价值如果你手头有一个Arduino项目,想让它和你的手机“说说话”,比如把传感器数据无线传到手机App上显示,或者用手机App远程控制几个LED灯,那么nRF8001这个蓝牙低功耗(BLE)模块绝对是你绕不…...
智能游戏助手:League Akari如何彻底改变你的英雄联盟体验
智能游戏助手:League Akari如何彻底改变你的英雄联盟体验 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否曾在英雄选择阶段手…...
动态提示词工程:让AI提示词具备上下文学习能力的实践指南
1. 项目概述:当提示词遇上上下文学习最近在折腾大语言模型应用时,我反复遇到一个痛点:精心设计的提示词(Prompt)在特定任务上效果拔群,但换个场景或数据,效果就大打折扣。每次都得重新调整、测试…...
