Spring Boot环境配置Envirnoment

news2024/11/22 18:11:44

Srping Boot 中我们使用 EnvironmentAware 注入 Environment 对象后,可以在 Environment 中获得系统参数,命令行采参数,文件配置等信息。

Environment 是如何存储,管理这些值的呢?变量发生冲突怎么办呢?我们可以扩展 Environment 的行为吗?本文结合 Spring Boot 启动时 Environment 的初始化过程,了解 Environment 的配置方式、优先级、配置源与扩展方式。

Spring 中的 Environment 指什么?

Spring 中的 Environment 是什么呢?了解 Environment 之前,不得不提到 Property 和 Profile。

我们在写项目的时候,经常会抽取一些配置项,在 Java 中通常叫做属性,也就是 Property,本质是一组键值对配置信息。使用配置项的好处在于修改起来很容易,只需修改下配置文件或命令行参数,然后重启一下就可以了。

开发过程中,大多数项目都有多套配置对应多个环境,一般来说有开发环境、测试环境和生产环境。这里的“环境”就叫做 Profile。程序可以读取到 Profile 的值,根据 Profile 的不同展示不同的特性。其实从本质上讲,“环境”也是一个“配置”,只是这个配置太重要了,也比较特殊,所以作为一个单独的概念来处理。

Environment = Property + Profile

Spring Boot 中,默认使用的 Environment 的实现类是 StandardServletEnvironment,我们可以通过它的类图了解 Spring Boot 中的 Environment 是如何管理的。

PropertyResolver 接口负责 Property 的获取(通过 key 获得 value),Environment 继承了这个接口,加入获得 Profile 的内容。ConfigurablePropertyResolver 继承了 PropertyResolver,为了解决 Property 的获取过程中涉及到的数据类型的转换和${…}表达式的解析问题。ConfigurableEnvironment 在此基础上,加入了 Profile 的设置功能。ConfigurableWebEnvironment 扩展了 web 功能,将 servlet 上下文作为配置源。

AbstractEnvironment,StandardEnvironment,StandardServletEnvironment 都是 Spring 对上述功能的实现。

Spring Boot 中的配置来自哪里?

Spring Boot 中的配置来自不同的地方,最常见的来自于 application.properties、application.yaml、环境变量和命令行参数。我们可以在 Spring Boot 的官方文档看到各种各样的配置方式。

官方一共给出了 14 中配置方式,并且给出了配置的优先级。数字越大优先级越高。

  • 通过硬编码的方式(SpringApplication.setDefaultProperties)进行配置。
  • 在 Spring Boot 的配置类上使用 @PropertySource 注解指定配置文件。
  • 使用配置文件 (比如 application.properties 文件)。
  • 通过 random.* 配置的随机属性。
  • 操作系统中的环境变量。
  • Java 的系统属性,可通过 System.getProperties() 获得相关内容。
  • java:comp/env 中 JNDI 属性。
  • ServletContext 初始化参数(web 环境)
  • ServletConfig 初始化参数(web 环境)
  • SPRING_APPLICATION_JSON 属性,该属性以 JSON 形式存储在系统环境变量中。
  • 命令行参数,类似于 java -jar -Denv=DEV 之类。
  • @SpringBootTest 注解,仅在测试中使用。
  • @TestPropertySource 注解,仅在测试中使用。
  • 激活 devtools 时,位于 $HOME/.config/spring-boot 下的配置。

如此之多的配置方式,且配置项的来源是多样化的,如何对用户暴露这些配置呢?一种方式就是将所有来源都暴露给用户,用户可以从任意配置源中获得配置。还有一种方式就是由 Spring 管理这些配置源,内部排好优先级,对外暴露统一的 get 方法,用户不需要知道其中的细节。Spring 显然使用了后者。

Spring 使用 PropertySource 来表示一个配置源,PropertySource 有很多子类,比如 SystemEnvironmentPropertySource,PropertiesPropertySource 等等。Spring 将这些 PropertySource 维护在一个列表中,当用户想要获得一个配置的时候,Spring 会遍历这些配置源,依次判断是否有匹配的配置。配置源在列表中的数据其实就代表了优先级。

如下是 Spring 从 propertySources 中获得 Property 的方式。

protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
  if (this.propertySources != null) {
    for (PropertySource<?> propertySource : this.propertySources) {

      Object value = propertySource.getProperty(key);
      if (value != null) {
        if (resolveNestedPlaceholders && value instanceof String) {
          value = resolveNestedPlaceholders((String) value);
        }
        logKeyFound(key, propertySource, value);
        return convertValueIfNecessary(value, targetValueType);
      }
    }
  }
  return null;
}

综上,Spring Boot 中的 Environment 中维护了若干个 PropertySource,也就是配置源,所有的配置到来自于这些配置源。

java 通过System.getProperties()获取系统参数

java.version Java 运行时环境版本

java.vendor Java 运行时环境供应商

java.vendor.url Java 供应商的 URL

java.home Java 安装目录

java.vm.specification.version Java 虚拟机规范版本

java.vm.specification.vendor Java 虚拟机规范供应商

java.vm.specification.name Java 虚拟机规范名称

java.vm.version Java 虚拟机实现版本

java.vm.vendor Java 虚拟机实现供应商

java.vm.name Java 虚拟机实现名称

java.specification.version Java 运行时环境规范版本

java.specification.vendor Java 运行时环境规范供应商

java.specification.name Java 运行时环境规范名称

java.class.version Java 类格式版本号

java.class.path Java 类路径

java.library.path 加载库时搜索的路径列表

java.io.tmpdir 默认的临时文件路径

java.compiler 要使用的 JIT 编译器的名称

java.ext.dirs 一个或多个扩展目录的路径

os.name 操作系统的名称

os.arch 操作系统的架构

os.version 操作系统的版本

file.separator 文件分隔符(在 UNIX 系统中是“/”)

path.separator 路径分隔符(在 UNIX 系统中是“:”)

line.separator 行分隔符(在 UNIX 系统中是“/n”)

user.name 用户的账户名称

user.home 用户的主目录

user.dir 用户的当前工作目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761452.html

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

相关文章

Linux--fork创建子进程,操作系统都做了什么

一句话总结&#xff1a;为该进程创建内核数据结构task_struct、地址空间mm_struct、页表并创建映射关系&#xff0c;一定程度上还要将该进程的代码和数据加载进内存 以下是对上面的解释&#xff1a; 首先&#xff0c;fork创建子进程&#xff0c;是不是操作系统里多了一个进程&…

Android ART虚拟机系列: 虚拟机CheckPoint机制分析

背景 在Android ART虚拟机中&#xff0c;GC的部分流程中会执行stop the world的操作&#xff0c;那么&#xff0c;STW在虚拟机中如何实现呢&#xff1f;本文就深入到ART虚拟机源码中&#xff0c;探寻STW的实现过程。 【本文基于android12源码分析】 CheckPoint机制 ART虚拟机…

SPSS数据文件的合并

数据文件合并的方式分为个案合并和变量合并。 个案合并指在两个数据文件拥有同共同变量时&#xff0c;将其中一个数据文件的个案合并到另一个数据文件中。变量合并指在两个数据文件拥有共同个案时&#xff0c;将其中一个数据文件的变量合并到另一个数据文件相应的个案中。 1…

文心一言 VS 讯飞星火 VS chatgpt (60)-- 算法导论6.4 4题

文心一言 VS 讯飞星火 VS chatgpt &#xff08;60&#xff09;-- 算法导论6.4 4题 四、证明&#xff1a;在最坏情况下&#xff0c;HEAPSORT 的时间复杂度是Ω (nlgn)。 文心一言&#xff1a; 要证明在最坏情况下&#xff0c;HEAPSORT 的时间复杂度是 Ω(n log n)&#xff0c…

Asymmetric Student-Teacher Networks for Industrial Anomaly Detection

用于工业异常检测的不对称学生-教师网络 摘要介绍模型架构总体介绍&#xff1a;教师网络学生网络 实验结论 时间&#xff1a;2022.10.14 期刊&#xff1a;WACV 之前师生网络结构的不足&#xff1a; 具有类似体系结构的学生网络&#xff0c;当输入不属于训练分布的数据时&#…

前端 | (三)表单及HTML4收尾 | 尚硅谷前端html+css零基础教程2023最新

学习来源&#xff1a;尚硅谷前端htmlcss零基础教程&#xff0c;2023最新前端开发html5css3视频 文章目录 &#x1f4da;表单&#x1f407;基本结构&#x1f407;常用表单控件⭐️文本输入框⭐️密码输入框⭐️单选框⭐️复选框⭐️隐藏域⭐️提交按钮⭐️重置按钮⭐️普通按钮⭐…

【雕爷学编程】Arduino动手做(83)---模拟SG90舵机模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

一个Spring Session JDBC例子

Spring Session JDBC是Spring Session项目的一部分&#xff0c;它提供了一种将会话数据存储在关系型数据库中的方法。Spring Session是一个用于在分布式环境中管理和共享会话的解决方案&#xff0c;它允许您通过不同的会话存储后端&#xff08;如内存、关系型数据库、NoSQL数据…

使用torch.nn包来构建神经网络

神经网络 可以使用torch.nn包来构建神经网络. 我们已经介绍了autograd包&#xff0c;nn包则依赖于autograd包来定义模型并对它们求导。一个nn.Module包含各个层和一个forward(input)方法&#xff0c;该方法返回output。 例如&#xff0c;下面这个神经网络可以对数字进行分类…

xss跨站脚本攻击总结

XSS(跨站脚本攻击) 跨站脚本攻击&#xff08;Cross Site Scripting&#xff09;&#xff0c;为了不和层叠样式表&#xff08;Cascading Style Sheets &#xff09;CSS的缩写混淆&#xff0c;故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当…

047、TiDB特性_TopSQL

TopSQL 之前 之前没有办法找单个TiKV Server的语句。只能查找整个集群的慢语句。 TopSQL之后 指定TiDB及TiKV实例正在执行的SQL语句CPU开销最多的Top 5 SQL每秒请求数、平均延迟等信息 TopSQL 使用 选择需要观察负载的具体TiDB Server或TiKV实例 观察Top 5 类SQL 查看某…

Linux 自动化构建工具(make/Makefile)

绪论 拼着一切代价&#xff0c;奔你的前程。——巴尔扎克. 本章继续学习Linux常用的工具&#xff0c;make是可以帮我们解决一些重复使用相同指令的冗杂的自动化构建工具。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&#xff1a;红色&…

TortoiseGit 入门指南08:浏览引用以及在引用间切换

在上一节 创建分支 中&#xff0c;我们学会了在分支上开发新功能&#xff0c;那么随之而来的问题是&#xff1a;如何查看项目又多少分支&#xff1f;如何再切换到主分支&#xff1f;这节来解决这些问题。 在回答之前&#xff0c;需要先了解一个 Git 术语&#xff1a;引用&…

学无止境·MySQL⑨(MongoDB)

MongoDB的安装及使用 MongoDB1、MongoDB的安装与启动2、创建一个数据库 名字grade3、数据库中创建一个集合名字 class4、集合中插入若干数据文档格式如下5、查找查看班级所有人信息查看班级中年龄为8岁的学生信息查看年龄大于10岁的学生信息查看年龄在 4---8岁之间的学生信息找…

接口测试之基于SaaS平台的iHRM项目的前端部署配置(踩坑版)

基于SaaS平台的iHRM项目的前端部署配置 下载安装node.js3.从Git上下载项目安装依赖包的改进方法 关于的部署可以参考基于SaaS平台的iHRM项目的前端部署教程博客 但本人在参考配置的过程中遇到了很多问题…于是写下这篇博客 下载安装node.js 可以访问https://nodejs.org/en下载…

利用Python绘制直方图和散点图

1 问题 利用python如何绘制直方图和散点图。 2 方法 # ------ 直方图import matplotlib.pyplot as pltimport numpy as npimport matplotlib# 设置matplotlib正常显示中文和负号matplotlib.rcParams[font.sans-serif] [SimHei] # 用黑体显示中文matplotlib.rcParams[axes.unic…

前端学习记录~2023.7.3~CSS杂记 Day4

前言一、溢出1. 默认情况2. overflow属性3. BFC 二、CSS 的值与单位1. 长度&#xff08;1&#xff09;绝对长度单位&#xff08;2&#xff09;相对长度单位 2、百分比3、数字4、颜色&#xff08;1&#xff09;颜色关键字&#xff08;2&#xff09;十六进制 RGB 值&#xff08;3…

单片机第一季:零基础7——定时器和计时器

目录 1&#xff0c;单片机定时器原理 2&#xff0c;51单片机定时器/计数器结构 3&#xff0c;定时器配置 4&#xff0c;示例代码-通过定时器控制LED灯间隔1s闪烁 51 单片机有两组定时器/计数器&#xff0c;因为既可以定时&#xff0c;又可以计数&#xff0c;故称之为定时…

JPA实现多对多关系

本文已收录于专栏 《Java》 目录 概念说明优势利弊实现方式通过两个ManyToMany注解实现类图代码 通过OneToMany和ManyToOne注解实现类图代码 总结提升 概念说明 多对多关系是指两个实体之间存在多对多的关联关系。在数据库中&#xff0c;多对多关系无法直接表示&#xff0c;需要…

javascript截取两个符号之间的字符串(2):lastIndexOf匹配和正则表达式匹配

lastIndexOf匹配和正则表达式匹配 项目需求1.规范的字符串2.不规范的字符串3-1.万能封装3-2.ChatGPT的优化写法4.正则表达式的用法5.补充知识&#xff1a;lastIndexOf的用法 项目需求 javascript中截取字符串中最后一个“/”和“?”之间的内容。 1.规范的字符串 https://tes…