参考:https://docs.spring.io/spring-boot/docs/1.5.17.RELEASE/reference/htmlsingle/#boot-features-external-config-yaml
YAML是JSON的超集,因此对于指定分层配置数据来说是一种非常方便的格式。 只要在类路径上有SnakeYAML库,SpringApplication类就会自动支持YAML配置。
注:如果使用spring-boot-starter,将通过自动提供SnakeYAML。
1. 加载YAML
Spring Framework提供了两个方便的类,可用于加载YAML文档。 YamlPropertiesFactoryBean将YAML作为Properties加载,YamlMapFactoryBean将YAML作为Map加载。
例如,下面的配置:
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
将转化为这些属性:
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML列表表示如下:
my:
servers:
- dev.bar.com
- foo.bar.com
将转化为这些属性:
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
要使用Spring DataBinder实用程序(这是@ConfigurationProperties所做的)绑定到类似的属性,需要在java.util.List(或Set)类型的目标bean中拥有一个属性,并且需要提供一个setter,或者用可变值初始化它,例如 这将绑定到上面的属性:
@ConfigurationProperties(prefix="my")
public class Config {
private List servers = new ArrayList();
public List getServers() {
return this.servers;
}
}
注:配置列表时需要格外小心,因为覆盖将无法正常工作。 在上面的示例中,当在多个位置重新定义my.servers时,各个元素的目标是覆盖,而不是列表。 要确保具有较高优先级的PropertySource可以覆盖列表,需要将其定义为单个属性:
my:
servers: dev.bar.com,foo.bar.com
2. 在Spring Environment中暴露YAML作为属性
YamlPropertySourceLoader类可用于在Spring环境中将YAML暴露为PropertySource。 这允许使用熟悉的@Value注释和占位符语法来访问YAML属性。
3. 多个YAML文档
可以使用spring.profiles属性在单个文件中指定多个配置文件的YAML文档,以指示文档何时可以使用。 例如:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
在上面的示例中,如果开发配置文件处于active状态,则server.address属性将为127.0.0.1。 如果未启用开发和生产配置文件,则属性的值将为192.168.1.100。
如果在应用程序上下文启动时没有显式活动,则激活默认配置文件。 因此,在此YAML中,我们为security.user.password设置了一个值,该值仅在“默认”配置文件中可用:
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak
而在此示例中,始终设置密码,因为它未附加到任何配置文件,并且必须在必要时在所有其他配置文件中显式重置:
server:
port: 8000
security:
user:
password: weak
使用“spring.profiles”元素指定的spring profile可以选择使用 ! 字符否定。 如果为单个文档指定了否定和非否定的配置文件,则至少一个非否定的配置文件必须匹配,并且没有否定的配置文件可以匹配。
4. YAML的缺点
无法通过@PropertySource注解加载YAML文件。 因此,如果需要以这种方式加载值,则需要使用属性文件(.properties)。
5. 合并YAML列表
任何YAML内容最终都会转换为属性。 例如,假设具有名称和描述属性的MyPojo对象默认为null。示例:
@ConfigurationProperties("foo")
public class FooProperties {
private final List list = new ArrayList<>();
public List getList() {
return this.list;
}
}
考虑以下配置:
foo:
list:
- name: my name
description: my description
---
spring:
profiles: dev
foo:
list:
- name: my another name
如果dev配置文件未激活,则FooProperties.list将包含一个如上定义的MyPojo条目。 但是,如果启用了dev配置文件,则列表仍将只包含一个条目(名称为“my another name”,描述为null)。 此配置不会将第二个MyPojo实例添加到列表中,也不会合并项目。
在多个配置文件中指定集合时,将使用具有最高优先级的集合(并且仅使用该集合):
foo:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
foo:
list:
- name: my another name
在上面的示例中,考虑到dev配置文件处于活动状态,FooProperties.list将包含一个MyPojo条目(名称为“my another name”,描述为null)。