应用程序启动时,Spring Boot就会从以下位置自动查找并加载application.properties
和application.yaml
文件:
- 类路径的根目录
- 类路径的
/config
包 - 当前目录
- 当前目录中的
/config
子目录 /config
子目录的直接子目录
该列表按优先级排序(后面项的值覆盖前面项的值)。已加载文件的文档将被作为PropertySources
,添加到Spring的Environment
中。
如果您不喜欢将application
作为配置文件名,可以通过指定spring.config.name
环境属性来切更换成另一个文件名。您还可以使用spring.config.location
环境属性(它是一个使用逗号分隔的目录位置或文件路径的列表)来引用显式位置。以下示例显示如何指定其他文件名:
$ java -jar myproject.jar --spring.config.name=myproject
下面的示例演示如何指定两个位置:
$ java -jar myproject.jar --spring.config.location=optional:classpath:/default.properties,optional:classpath:/override.properties
如果位置是可选的并且不介意它们是否不存在,则使用
optional:
前缀。
spring.config.name
和spring.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/
,则被考虑位置的完整集合为:
optional:classpath:custom-config/
optional:file:./custom-config/
如果您希望添加其他位置,而不是替换它们,则可以使用spring.config.additional-location
。从其他位置加载的文件中属性可以覆盖默认位置的。例如,如果将spring.config.additional-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
选择的任何其他基本名称)文件中为您的应用程序提供默认值;然后,在运行时,可以使用其中一个自定义位置中的其他文件覆盖这些默认值。
如果您使用环境变量而不是系统属性,则大多数操作系统都不允许使用句点分隔的键名,但是可以使用下划线代替(例如,
SPRING_CONFIG_NAME
代替spring.config.name
)。有关详细信息,请参见从环境变量绑定。如果您的应用程序在Servlet容器或应用程序服务器中运行,则可以使用JNDI属性(在
java:comp/env
中)或Servlet上下文初始化参数来代替环境变量或系统属性,也可以与它们一起使用。
2.3.1 可选位置
默认情况下,当指定的配置数据位置不存在时,Spring Boot将抛出ConfigDataLocationNotFoundException
异常,并且您的应用程序将不会启动。
如果要指定位置,但不介意它是否总是存在,则可以使用optional:
前缀。您可以将此前缀与spring.config.location
和spring.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.location
和spring.config.additional-location
属性中使用通配符位置。
通配符位置必须仅包含一个
*
,对于目录搜索位置必须以*/
结尾,对于文件搜索位置必须以*/<filename>
结尾。 带通配符的位置根据文件名的绝对路径按字母顺序排序。通配符位置仅适用于外部目录。您不能在某个
classpath:
位置上使用通配符。
2.3.3 配置(Profile)专用文件
除了application
属性文件,Spring Boot还将尝试使用application-{profile}
命名约定来加载特定于配置的文件。例如,如果你的应用程序启动了一个配置名为prod
的YAML格式的文件,则application.yml
和application-prod.yml
文件都在配置文件加载的考虑范围内。
特定于配置的属性文件也是从与标准application.properties
文件相同的位置加载的,特定于配置的文件始终会覆盖非特定配置文件。如果指定了多个特定于配置的文件,则采用后赢策略。例如,如果属性spring.profiles.active
属性指定了特定配置为prod,live
,则application-prod.properties
中的值会被application-live.properties
中的值覆盖。
如果没有活动的特定配置被设置,在Environment
中有一组默认的配置(默认是[default]
)。换句话说,如果未明确激活任何特定的配置,则来自于application-default
的属性将被考虑使用。
属性文件仅被加载一次。如果您已经直接导入了特定于配置文件的属性文件,则不会再次导入。
2.3.4 导入其他数据
应用程序属性可以使用spring.config.import
属性从其他位置导入其他配置数据。当文件被发现时,导入时对其进行处理,并将其视为额外的文档,而不在原始属性文件下面声明导入。
例如,您的类路径下的application.properties
文件中可能包含以下内容:
Properties:
spring.application.name=myapp
spring.config.import=optional:file:./dev.properties
Yaml:
spring:
application:
name: "myapp"
config:
import: "optional:file:./dev.properties"
这将触发导入当前目录中dev.properties
文件(如果存在这样的文件)。来自被导入的dev.properties
文件中的值将优先于触发导入的文件。在上面的示例中,dev.properties
可以将spring.application.name
中声明的值重新定义。
可以在一个spring.config.import
键下指定多个位置。位置将按照定义的顺序进行处理,后导入的优先于先导入的。
Spring Boot包含插件化的API,允许支持各种不同位置的地址。默认情况下,您可以导入Java Properties、YAML和“配置树”。 第三方jar可以为其他技术提供支持(不需要文件位于本地)。例如,您可以想象配置数据来自外部存储、例如Consul,Apache ZooKeeper或Netflix Archaius。 如果要支持自己的位置,请参阅
org.springframework.boot.context.config
包中的ConfigDataLocationResolver
和ConfigDataLoader
类。
2.3.5 导入无扩展名文件
某些云平台无法给已装载卷的文件中添加后缀名。要导入这些无扩展名的文件,您需要给Spring Boot一个提示,以便它知道如何加载它们。您可以通过在方括号中添加扩展提示来做到这一点。
例如,假设您有一个/etc/config/myconfig
文件,想将其作为yaml文件导入。您可以在application.properties
文件中使用以下方法导入它:
Properties:
spring.config.import=file:/etc/config/myconfig[.yaml]
Yaml:
spring:
config:
import: "file:/etc/config/myconfig[.yaml]"
2.3.6 使用配置树
在云平台上运行应用程序(例如Kubernetes)时,您通常需要读取平台提供的配置值。为此目的,使用环境变量并不罕见,但是这样做可能会有弊端,特别是如果该值应该保密的话。
作为环境变量的替代方法,许多云平台现在允许您将配置映射到装入的数据卷中。例如,Kubernetes可以批量挂载ConfigMaps
和Secrets
。
可以使用两种常见的卷挂载模式:
- 单个文件包含完整的属性集(通常写为YAML)。
- 多个文件被写入目录树,文件名成为“键”,内容成为“值”。
对于第一种情况,可以如上面描述的那样,使用spring.config.import
直接导入YAML或Properties文件。对于第二种情况,需要使用configtree:
前缀,以便Spring Boot知道它需要将所有文件暴露为属性。
例如,让我们想象一下Kubernetes已经挂载了以下卷:
etc/
config/
myapp/
username
password
username
文件的内容将是一个配置值,password
的是一个密码。
要导入这些属性,可以将以下内容添加到application.properties
或application.yaml
文件中:
Properties:
spring.config.import=optional:configtree:/etc/config
Yaml:
spring:
config:
import: "optional:configtree:/etc/config/"
然后,您可以按照通常的方式,从Environment
中访问或注入myapp.username
和myapp.password
属性。
可以根据期望的内容将配置树的值绑定到字符串
String
和byte[]
类型。
如果要从同一父文件夹导入多个配置树,则可以使用通配符快捷方式。任何以/*/
结尾的configtree:
位置,将所有直接子级都导入为配置树。
例如,给定以下的卷:
etc/
config/
dbconfig/
db/
username
password
mqconfig/
mq/
username
password
您可以将configtree:/etc/config/*/
作为导入位置:
Properties:
spring.config.import=optional:configtree:/etc/config/*/
Yaml:
spring:
config:
import: "optional:configtree:/etc/config/*/"
这将增加db.username
,db.password
,mq.username
和mq.password
属性。
使用通配符加载的目录按字母顺序排序。如果您需要其他的排序顺序,则应将每个位置罗列出来单独导入
2.3.7 属性占位符
在使用application.properties
和application.yml
中的值时,它们会通过现有的Environment
值进行过滤,因此您可以参考前面定义的值(例如,在“系统”属性中的值)。标准的${name}
属性占位符(property-placeholder)语法可以在属性值中的任何位置使用。
例如,以下文件将设置app.description
的值为“ MyApp is a Spring Boot application”:
Properties:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
Yaml:
app:
name: "MyApp"
description: "${app.name} is a Spring Boot application"
您还可以使用此技术来创建现有Spring Boot属性的“简短”变体。有关详细信息,请参见怎样做。
2.3.8 处理多文档文件
Spring Boot允许您将单个物理文件拆分为多个逻辑文档,每个逻辑文档都被独立添加。从上到下按顺序处理文档。后面的文档中定义的属性可以覆盖前面的。
对于application.yml
文件,使用标准的YAML多文档语法。三个连续的连字符代表一个文档的末尾,以及下一个文档的开始。
例如,以下文件具有两个逻辑文档(译者:个人感觉下面的语法不想是YAML的,更像是Properties的):
spring.application.name: MyApp
---
spring.config.activate.on-cloud-platform: kubernetes
spring.application.name: MyCloudApp
对于application.properties
文件,特殊的#---
注释用于标记文档拆分:
spring.application.name=MyApp
#---
spring.config.activate.on-cloud-platform=kubernetes
spring.application.name=MyCloudApp
属性文件分隔符不得包含任何前导或尾随空格,并且必须恰好具有三个连字符。
多文档属性文件通常与激活属性(例如,
spring.config.activate.on-profile
)结合使用。有关详细信息,请参见下一部分。
2.3.9 激活属性
仅在满足某些条件时,才激活给定的属性,有时这是很有用的。例如,仅当特定配置文件处于活动状态时, 您可能才具有相关的属性。
您可以使用spring.config.activate.*
来有条件地激活一个属性文档。
可以使用以下激活属性:
表2.激活属性
属性 | 注意事项 |
---|---|
on-profile |
必须匹配的配置表达式才能使文档处于活动状态 |
on-cloud-platform |
必须检测到CloudPlatform 才能使得文件激活 |
例如,仅当在Kubernetes上运行,并且当“ prod”或“ staging”配置文件处于活动状态时,以下特定的内容(第二个文档)才处于活动状态:
Properties:
myprop=always-set
#---
spring.config.activate.on-cloud-platform=kubernetes
spring.config.activate.on-profile=prod | staging
myotherprop=sometimes-set
Yaml:
myprop:
always-set
---
spring:
config:
activate:
on-cloud-platform: "kubernetes"
on-profile: "prod | staging"
myotherprop: sometimes-set