应用程序启动时,Spring Boot就会从以下位置自动查找并加载application.propertiesapplication.yaml文件:

  1. 类路径的根目录
  2. 类路径的/config
  3. 当前目录
  4. 当前目录中的/config子目录
  5. /config子目录的直接子目录

该列表按优先级排序(后面项的值覆盖前面项的值)。已加载文件的文档将被作为PropertySources,添加到Spring的Environment中。
如果您不喜欢将application作为配置文件名,可以通过指定spring.config.name环境属性来切更换成另一个文件名。您还可以使用spring.config.location环境属性(它是一个使用逗号分隔的目录位置或文件路径的列表)来引用显式位置。以下示例显示如何指定其他文件名:

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

下面的示例演示如何指定两个位置:

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

灯泡.svg 如果位置是可选的并且不介意它们是否不存在,则使用optional:前缀。

警告.svg spring.config.namespring.config.location很早就被用于确定必须加载哪些文件。必须将它们定义为环境属性(通常地,是OS环境变量、系统属性或命令行参数)。

如果spring.config.location包含目录(而不是文件),则应以/结尾(在运行时,在被加载之前,它们将追加spring.config.name生成的名称)。spring.config.location指定的文件按原样使用。无论是直接指定还是指定所在目录,配置文件都必须在名称中包含文件扩展名。支持开箱即用的典型后缀名有.properties.yaml.yml
如果指定了多个位置,则后指定的位置可以覆盖前面指定的。
使用spring.config.location配置的位置替换默认位置。例如,如果spring.config.location的值配置为 optional:classpath:/custom-config/,optional:file:./custom-config/,则被考虑位置的完整集合为:

  1. optional:classpath:custom-config/
  2. optional:file:./custom-config/

如果您希望添加其他位置,而不是替换它们,则可以使用spring.config.additional-location。从其他位置加载的文件中属性可以覆盖默认位置的。例如,如果将spring.config.additional-location的值配置成optional:classpath:/custom-config/,optional:file:./custom-config/,则考虑位置的完整集合为:

  1. optional:classpath:/
  2. optional:classpath:/config/
  3. optional:file:./
  4. optional:file:./config/*/
  5. optional:file:./config/
  6. optional:classpath:custom-config/
  7. optional:file:./custom-config/

通过此搜索顺序,您可以在一个配置文件中指定默认值,然后在另一个配置文件中有选择地覆盖这些值。您可以在其中一个默认位置的application.properties(或使用spring.config.name选择的任何其他基本名称)文件中为您的应用程序提供默认值;然后,在运行时,可以使用其中一个自定义位置中的其他文件覆盖这些默认值。

info.svg 如果您使用环境变量而不是系统属性,则大多数操作系统都不允许使用句点分隔的键名,但是可以使用下划线代替(例如,SPRING_CONFIG_NAME代替spring.config.name)。有关详细信息,请参见从环境变量绑定

info.svg 如果您的应用程序在Servlet容器或应用程序服务器中运行,则可以使用JNDI属性(在java:comp/env中)或Servlet上下文初始化参数来代替环境变量或系统属性,也可以与它们一起使用。

2.3.1 可选位置

默认情况下,当指定的配置数据位置不存在时,Spring Boot将抛出ConfigDataLocationNotFoundException异常,并且您的应用程序将不会启动。
如果要指定位置,但不介意它是否总是存在,则可以使用optional:前缀。您可以将此前缀与spring.config.locationspring.config.additional-location属性、以及spring.config.import声明一起使用。
例如,spring.config.import值为optional:file:./myconfig.properties,即使myconfig.properties文件丢失,也允许您的应用程序启动。
如果要忽略所有的ConfigDataLocationNotFoundExceptions,并始终继续启动应用程序,则可以使用spring.config.on-not-found属性。使用SpringApplication.setDefaultProperties(…)或与系统/环境变量一起使用,将值设置为ignore。(这句话,感觉原文有问题,等release之后再找到这句话翻译)

2.3.2 通配符位置

如果配置文件位置的最后一个路径段包括*字符,则将其视为通配符位置。加载配置时,通配符会展开,以便也检查直接子目录。当配置属性有多个来源时,通配符位置在诸如Kubernetes之类的环境中特别有用。
例如,如果您具有一些Redis配置和某些MySQL配置,则可能需要将这两类配置分开,同时要求这两类配置都存在于application.properties文件中。这可能会导致两个不同的application.properties文件放置在不同的位置(如,/config/redis/application.properties/config/mysql/application.properties)。在这种情况下,通配符位置为config/*/,将导致两个文件都被处理。
默认情况下,Spring Boot在默认搜索位置中包含config/*/。这意味着将搜索jar外部目录的所有的/config的子目录。
您可以在spring.config.locationspring.config.additional-location属性中使用通配符位置。

info.svg 通配符位置必须仅包含一个*,对于目录搜索位置必须以*/结尾,对于文件搜索位置必须以*/<filename>结尾。 带通配符的位置根据文件名的绝对路径按字母顺序排序。

灯泡.svg 通配符位置仅适用于外部目录。您不能在某个classpath:位置上使用通配符。

2.3.3 配置(Profile)专用文件

除了application属性文件,Spring Boot还将尝试使用application-{profile}命名约定来加载特定于配置的文件。例如,如果你的应用程序启动了一个配置名为prod的YAML格式的文件,则application.ymlapplication-prod.yml文件都在配置文件加载的考虑范围内。
特定于配置的属性文件也是从与标准application.properties文件相同的位置加载的,特定于配置的文件始终会覆盖非特定配置文件。如果指定了多个特定于配置的文件,则采用后赢策略。例如,如果属性spring.profiles.active属性指定了特定配置为prod,live,则application-prod.properties中的值会被application-live.properties中的值覆盖。
如果没有活动的特定配置被设置,在Environment中有一组默认的配置(默认是[default])。换句话说,如果未明确激活任何特定的配置,则来自于application-default的属性将被考虑使用。

info.svg 属性文件仅被加载一次。如果您已经直接导入了特定于配置文件的属性文件,则不会再次导入。

2.3.4 导入其他数据

应用程序属性可以使用spring.config.import属性从其他位置导入其他配置数据。当文件被发现时,导入时对其进行处理,并将其视为额外的文档,而不在原始属性文件下面声明导入。
例如,您的类路径下的application.properties文件中可能包含以下内容:
Properties:

  1. spring.application.name=myapp
  2. spring.config.import=optional:file:./dev.properties

Yaml:

  1. spring:
  2. application:
  3. name: "myapp"
  4. config:
  5. import: "optional:file:./dev.properties"

这将触发导入当前目录中dev.properties文件(如果存在这样的文件)。来自被导入的dev.properties文件中的值将优先于触发导入的文件。在上面的示例中,dev.properties可以将spring.application.name中声明的值重新定义。
可以在一个spring.config.import键下指定多个位置。位置将按照定义的顺序进行处理,后导入的优先于先导入的。

灯泡.svg Spring Boot包含插件化的API,允许支持各种不同位置的地址。默认情况下,您可以导入Java Properties、YAML和“配置树”。 第三方jar可以为其他技术提供支持(不需要文件位于本地)。例如,您可以想象配置数据来自外部存储、例如Consul,Apache ZooKeeper或Netflix Archaius。 如果要支持自己的位置,请参阅org.springframework.boot.context.config包中的ConfigDataLocationResolverConfigDataLoader类。

2.3.5 导入无扩展名文件

某些云平台无法给已装载卷的文件中添加后缀名。要导入这些无扩展名的文件,您需要给Spring Boot一个提示,以便它知道如何加载它们。您可以通过在方括号中添加扩展提示来做到这一点。
例如,假设您有一个/etc/config/myconfig文件,想将其作为yaml文件导入。您可以在application.properties文件中使用以下方法导入它:
Properties:

  1. spring.config.import=file:/etc/config/myconfig[.yaml]

Yaml:

  1. spring:
  2. config:
  3. import: "file:/etc/config/myconfig[.yaml]"

2.3.6 使用配置树

在云平台上运行应用程序(例如Kubernetes)时,您通常需要读取平台提供的配置值。为此目的,使用环境变量并不罕见,但是这样做可能会有弊端,特别是如果该值应该保密的话。
作为环境变量的替代方法,许多云平台现在允许您将配置映射到装入的数据卷中。例如,Kubernetes可以批量挂载ConfigMapsSecrets
可以使用两种常见的卷挂载模式:

  1. 单个文件包含完整的属性集(通常写为YAML)。
  2. 多个文件被写入目录树,文件名成为“键”,内容成为“值”。

对于第一种情况,可以如上面描述的那样,使用spring.config.import直接导入YAML或Properties文件。对于第二种情况,需要使用configtree:前缀,以便Spring Boot知道它需要将所有文件暴露为属性。
例如,让我们想象一下Kubernetes已经挂载了以下卷:

  1. etc/
  2. config/
  3. myapp/
  4. username
  5. password

username文件的内容将是一个配置值,password的是一个密码。
要导入这些属性,可以将以下内容添加到application.propertiesapplication.yaml文件中:
Properties:

  1. spring.config.import=optional:configtree:/etc/config

Yaml:

  1. spring:
  2. config:
  3. import: "optional:configtree:/etc/config/"

然后,您可以按照通常的方式,从Environment中访问或注入myapp.usernamemyapp.password属性。

灯泡.svg 可以根据期望的内容将配置树的值绑定到字符串Stringbyte[]类型。

如果要从同一父文件夹导入多个配置树,则可以使用通配符快捷方式。任何以/*/结尾的configtree:位置,将所有直接子级都导入为配置树。
例如,给定以下的卷:

  1. etc/
  2. config/
  3. dbconfig/
  4. db/
  5. username
  6. password
  7. mqconfig/
  8. mq/
  9. username
  10. password

您可以将configtree:/etc/config/*/作为导入位置:
Properties:

  1. spring.config.import=optional:configtree:/etc/config/*/

Yaml:

  1. spring:
  2. config:
  3. import: "optional:configtree:/etc/config/*/"

这将增加db.usernamedb.passwordmq.usernamemq.password属性。

info.svg 使用通配符加载的目录按字母顺序排序。如果您需要其他的排序顺序,则应将每个位置罗列出来单独导入

2.3.7 属性占位符

在使用application.propertiesapplication.yml中的值时,它们会通过现有的Environment值进行过滤,因此您可以参考前面定义的值(例如,在“系统”属性中的值)。标准的${name}属性占位符(property-placeholder)语法可以在属性值中的任何位置使用。
例如,以下文件将设置app.description的值为“ MyApp is a Spring Boot application”:
Properties:

  1. app.name=MyApp
  2. app.description=${app.name} is a Spring Boot application

Yaml:

  1. app:
  2. name: "MyApp"
  3. description: "${app.name} is a Spring Boot application"

灯泡.svg 您还可以使用此技术来创建现有Spring Boot属性的“简短”变体。有关详细信息,请参见怎样做

2.3.8 处理多文档文件

Spring Boot允许您将单个物理文件拆分为多个逻辑文档,每个逻辑文档都被独立添加。从上到下按顺序处理文档。后面的文档中定义的属性可以覆盖前面的。
对于application.yml文件,使用标准的YAML多文档语法。三个连续的连字符代表一个文档的末尾,以及下一个文档的开始。
例如,以下文件具有两个逻辑文档(译者:个人感觉下面的语法不想是YAML的,更像是Properties的):

  1. spring.application.name: MyApp
  2. ---
  3. spring.config.activate.on-cloud-platform: kubernetes
  4. spring.application.name: MyCloudApp

对于application.properties文件,特殊的#---注释用于标记文档拆分:

  1. spring.application.name=MyApp
  2. #---
  3. spring.config.activate.on-cloud-platform=kubernetes
  4. spring.application.name=MyCloudApp

info.svg 属性文件分隔符不得包含任何前导或尾随空格,并且必须恰好具有三个连字符。

灯泡.svg 多文档属性文件通常与激活属性(例如,spring.config.activate.on-profile)结合使用。有关详细信息,请参见下一部分

2.3.9 激活属性

仅在满足某些条件时,才激活给定的属性,有时这是很有用的。例如,仅当特定配置文件处于活动状态时, 您可能才具有相关的属性。
您可以使用spring.config.activate.*来有条件地激活一个属性文档。
可以使用以下激活属性:

表2.激活属性

属性 注意事项
on-profile 必须匹配的配置表达式才能使文档处于活动状态
on-cloud-platform 必须检测到CloudPlatform才能使得文件激活

例如,仅当在Kubernetes上运行,并且当“ prod”或“ staging”配置文件处于活动状态时,以下特定的内容(第二个文档)才处于活动状态:
Properties:

  1. myprop=always-set
  2. #---
  3. spring.config.activate.on-cloud-platform=kubernetes
  4. spring.config.activate.on-profile=prod | staging
  5. myotherprop=sometimes-set

Yaml:

  1. myprop:
  2. always-set
  3. ---
  4. spring:
  5. config:
  6. activate:
  7. on-cloud-platform: "kubernetes"
  8. on-profile: "prod | staging"
  9. myotherprop: sometimes-set