1. 程式人生 > >SpringBoot(30) - Properties(2) - 使用YAML配置

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)。