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。它并不会合并。