0
点赞
收藏
分享

微信扫一扫

SpringBoot 外部化配置(Externalized Configuration)—官方原版

郝春妮 2023-05-08 阅读 113

一、概述

Spring Boot可以让你将配置外部化,这样你就可以在不同的环境中使用相同的应用程序代码。 你可以使用各种外部配置源,包括Java properties 文件、YAML文件、环境变量和命令行参数。

属性值可以通过使用 @Value 注解直接注入你的Bean,也可以通过Spring 的 Environment 访问,或者通过 @ConfigurationProperties 绑定到对象。

Spring Boot 使用一个非常特别的 PropertySource 顺序,旨在允许合理地重写值。 后面的 property source 可以覆盖前面属性源中定义的值。 按以下顺序考虑:

  1. 默认属性(通过 SpringApplication.setDefaultProperties 指定)。
  2. @Configuration 类上的 @PropertySource 注解。请注意,这样的属性源直到application context被刷新时才会被添加到环境中。这对于配置某些属性来说已经太晚了,比如 logging.* 和 spring.main.* ,它们在刷新开始前就已经被读取了。
  3. 配置数据(如 application.properties 文件)。
  4. RandomValuePropertySource,它只有 random.* 属性。
  5. 操作系统环境变量
  6. Java System properties (System.getProperties()).
  7. java:comp/env 中的 JNDI 属性。
  8. ServletContext init parameters.
  9. ServletConfig init parameters.
  10. 来自 SPRING_APPLICATION_JSON 的属性(嵌入环境变量或系统属性中的内联JSON)。
  11. 命令行参数
  12. 你在测试中的 properties 属性。在 @SpringBootTest 和测试注解中可用,用于测试你的应用程序的一个特定片断。
  13. 你测试中的https://docs.spring.io/spring-framework/docs/6.0.5/javadoc-api/org/springframework/test/context/TestPropertySource.html[@TestPropertySource] 注解.
  14. 当devtools处于活动状态时,$HOME/.config/spring-boot 目录下的Devtools全局设置属性。

配置数据文件按以下顺序考虑。

  1. 在你的jar中打包的Application properties(application.properties 和 YAML)。
  2. 在你的jar中打包的 特定的 Profile application properties(application-{profile}.properties 和 YAML)。
  3. 在你打包的jar之外的Application properties性(application.properties和YAML)。
  4. 在你打包的jar之外的特定的 Profile application properties( application-{profile}.properties 和YAML)。

为了提供一个具体的例子,假设你开发了一个 @Component,使用了一个 name 属性,如下面的例子所示:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

在你的应用程序的classpath(例如,在你的jar中),你可以有一个 application.properties 文件,为 name 提供一个合理的默认属性值。当在一个新的环境中运行时,可以在你的jar之外提供一个 application.properties 文件来覆盖 name 。对于一次性的测试,你可以用一个特定的命令行参数来启动(例如,java -jar app.jar --name="Spring")。

二、 访问命令行属性

默认情况下,SpringApplication 会将任何命令行选项参数(即以 -- 开头的参数,如 --server.port=9000 )转换为 property 并将其添加到Spring Environment 中。 如前所述,命令行属性总是优先于基于文件的属性源。

如果你不希望命令行属性被添加到 Environment 中,你可以通过 SpringApplication.setAddCommandLineProperties(false) 禁用它们。

三、 JSON Application Properties

环境变量和系统属性往往有限制,这意味着有些属性名称不能使用。 为了帮助解决这个问题,Spring Boot允许你将一个属性块编码为一个单一的JSON结构。

当你的应用程序启动时,任何 spring.application.json 或 SPRING_APPLICATION_JSON 属性将被解析并添加到 Environment 中。

例如,SPRING_APPLICATION_JSON 属性可以在 UN*X shell 的命令行中作为环境变量提供。

$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar

在前面的例子中,你在Spring的 Environment 中最终得到了 my.name=test

同样的JSON也可以作为一个系统属性提供。

$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar

或者你可以通过使用一个命令行参数来提供JSON。

$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'

如果你要部署到一个经典的应用服务器中,你也可以使用一个名为 java:comp/env/spring.application.json 的JNDI变量。

四、 外部的 Application Properties

当你的应用程序启动时,Spring Boot会自动从以下位置找到并加载 application.properties 和 application.yaml 文件。

  1. classpath
  1. classpath 根路径
  2. classpath 下的 /config 包
  1. 当前目录
  1. 当前目录下
  2. 当前目录下的 config/ 子目录
  3. config/ 子目录的直接子目录

列表按优先级排序(较低项目的值覆盖较早项目的值)。 加载的文件被作为 PropertySources 添加到Spring的 Environment 中。

如果你不喜欢 application 作为配置文件名称,你可以通过指定 spring.config.name 环境属性切换到另一个文件名称。 例如,为了寻找 myproject.properties 和 myproject.yaml 文件,你可以按以下方式运行你的应用程序。

$ java -jar myproject.jar --spring.config.name=myproject

你也可以通过使用 spring.config.location 环境属性来引用一个明确的位置。 该属性接受一个逗号分隔的列表,其中包含一个或多个要检查的位置。

下面的例子显示了如何指定两个不同的文件。

$ java -jar myproject.jar --spring.config.location=\
    optional:classpath:/default.properties,\
    optional:classpath:/override.properties

如果 配置文件是可选的,并且可以是不存在的,那么请使用 optional: 前缀。

pring.config.namespring.config.location, 和 spring.config.extra-location 很早就用来确定哪些文件必须被加载。 它们必须被定义为环境属性(通常是操作系统环境变量,系统属性,或命令行参数)。

如果 spring.config.location 包含目录(而不是文件),它们应该以 / 结尾。 在运行时,它们将被附加上由 spring.config.name 生成的名称,然后被加载。 在 spring.config.location 中指定的文件被直接导入

在大多数情况下,你添加的每个 spring.config.location 项将引用一个文件或目录。 位置是按照它们被定义的顺序来处理的,后面的位置可以覆盖前面的位置的值。
如果你有一个复杂的位置设置,而且你使用特定的配置文件,你可能需要提供进一步的提示,以便Spring Boot知道它们应该如何分组。一个位置组是一个位置的集合,这些位置都被认为是在同一级别。例如,你可能想把所有classpath位置分组,然后是所有外部位置。一个位置组内的项目应该用 ; 分隔。更多细节见 “指定 profile” 部分的例子。
通过使用 spring.config.location 配置的位置取代默认位置。 例如,如果 spring.config.location 被配置为 optional:classpath:/custom-config/,optional:file:./custom-config/ ,考虑的完整位置集如下:

optional:classpath:custom-config/

optional:file:./custom-config/

SpringBoot 外部化配置(Externalized Configuration)—官方原版_spring

如果你喜欢添加额外的位置,而不是替换它们,你可以使用 spring.config.extra-location 。 从附加位置加载的属性可以覆盖默认位置的属性。 例如,如果 spring.config.extra-location 被配置为 optional:classpath:/custom-config/,optional:file:./custom-config/ ,考虑的完整位置集如下:

optional:classpath:/;optional:classpath:/config/

optional:file:./;optional:file:./config/;optional:file:./config/*/

optional:classpath:custom-config/

optional:file:./custom-config/

这种搜索排序让你在一个配置文件中指定默认值,然后在另一个文件中选择性地覆盖这些值。 你可以在其中一个默认位置的 application.properties (或你用 spring.config.name 选择的其他basename)中为你的应用程序提供默认值。 然后,这些默认值可以在运行时被位于其中一个自定义位置的不同文件覆盖。

4.1、 可选的位置(Optional Locations)

默认情况下,当指定的配置数据位置不存在时,Spring Boot将抛出一个 ConfigDataLocationNotFoundException ,你的应用程序将无法启动。
如果你想指定一个位置,但你不介意它并不总是存在,你可以使用 optional: 前缀。你可以在 spring.config.location和spring.config.extra-location 属性中使用这个前缀,也可以在 spring.config.import 声明中使用。
例如,spring.config.import 值为 optional:file:./myconfig.properties 允许你的应用程序启动,即使 myconfig.properties 文件丢失。
如果你想忽略所有的 ConfigDataLocationNotFoundExceptions 并始终继续启动你的应用程序,你可以使用 spring.config.on-not-found 属性。 使用 SpringApplication.setDefaultProperties(..) 或使用系统/环境变量将其值设置为 ignore。

 4.2、 通配符地址

如果一个配置文件的位置在最后一个路径段中包含 * 字符,它就被认为是一个通配符位置。 通配符在加载配置时被扩展,因此,直接的子目录也被检查。 通配符位置在Kubernetes这种有多个配置属性的来源的环境中特别有用。
例如,如果你有一些Redis配置和一些MySQL配置,你可能想把这两部分配置分开,同时要求这两部分都存在于一个 application.properties 文件中。
这可能会导致两个独立的 application.properties 文件挂载在不同的位置,如 /config/redis/application.properties 和 /config/mysql/application.properties 。 在这种情况下,有一个通配符位置 config/*/ ,将导致两个文件被处理。
默认情况下,Spring Boot将 config/*/ 列入默认搜索位置。 这意味着你的jar之外的 /config 目录的所有子目录都会被搜索到。
你可以在 spring.config.location 和 spring.config.extra-location 属性中使用通配符位置。

大家好,我是Doker品牌的Sinbad,欢迎点赞和评论,您的鼓励是我们持续更新的动力!欢迎加微信进入技术群聊!


举报

相关推荐

0 条评论