SpringBoot(30) - Properties(2) - 使用YAML配置

参考: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<String> servers = new ArrayList<String>();

    public List<String> 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<MyPojo> list = new ArrayList<>();

    public List<MyPojo> 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)。

猜你喜欢

转载自blog.csdn.net/mytt_10566/article/details/83993653