springboot 外部配置<中篇> YAML文件代替屬性文件
YAML是JSON格式的擴展集,是一種非常方便的用來定義屬性的文件格式。當你的項目有SnakeYAML庫時,Spring Boot將會自動支持它。
1、使用YAML文件
SpringFramework中有兩個類可以加載YAML文件,YamlPropertiesFactoryBean
可以加載之為屬性類Properties
,YamlMapFactoryBean
可以加載之為Map。
加載YAML文件
如下YAML文件
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列表將會轉化為帶[index]字符串的Key,如
my: servers: - dev.bar.com - foo.bar.com
將被轉換為
my.servers[0]=dev.bar.com my.servers[1]=foo.bar.com
想要想Spring DataBinder工具(這裏用的是@ConfigurationProperties註解)那樣綁定對象到實體Bean中的List或Set屬性上的話,你不需要為改屬性提供setter或者初始化該屬性,只需要如下就行
@ConfigurationProperties(prefix="my") public class Config { private List<String> servers = new ArrayList<String>(); public List<String> getServers() {return this.servers; } }
2、暴露YAML文件至Spring Environment
通常用YamlPropertySourceLoader來將YAML文件作為屬性資源文件暴露給Spring Environment。這能讓你通過使用@Value註釋+占位符語法來訪問這些環境變量。
3、多重配置 YAML 文檔。
你可以在單個文件夾裏面配置多個重復的YAML 文檔並通過spring.profiles的值來表明你想用哪一個,例如:
server: address: 192.168.1.100 --- spring: profiles: development server: address: 127.0.0.1 --- spring: profiles: production server: address: 192.168.1.120
在上面例子中,開發環境中的服務器地址將是127.0.0.1,生產環境的服務器地址則為192.168.1.100,如果spring的profiles為不可用狀態,則為192.168.1.100。
在沒有指定的情況下profiles通常是激活的。所以在這個文件中我們設一個僅僅對"default" profiles有效的security.user.password。
server: port: 8000 --- spring: profiles: default security: user: password: weak
而在下面的例子中,密碼總是被設置因為它沒有被綁定到任何profiles,因此它會在所有其他的profiles裏面也都被重置。
4、YAML缺點
YAML文件不能通過@PropertySource註解進行加載。
5、YAML列表的合並
從上面我們可以看到,YAML最終被轉換成Properties。當通過profiles來覆蓋一個list屬性時候,程序將變成一個計數器往list添加數據。
例如,假設類MyPojo包含兩個默認為null的屬性name和discretion,讓我們通過FooProperties類來對他們進行暴露。
@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只包含一個entry即上面定義的。如果dev為激活狀態,也僅僅包含下面定義的entry。它並不會合並。
springboot 外部配置<中篇> YAML文件代替屬性文件