Spring Boot 不仅仅支持 Properties(.properties)属性配置文件,还支持 YAML(.yml)配置文件。
YAML 是 JSON 的一个超集,也是一种方便配置层次结构数据的格式。只要你将 SnakeYAML 库放到 classpath 下, Spring 应用就会自动支持 YAML,以作为 Properties 属性文件的替换。
注意:如果你的应用使用了 ”Starters“,且添加了 spring-boot-starter 依赖,则会自动加载 SnakeYAML 库。
Spring 框架提供两个便捷的类用于加载 YAML 文 档, YamlPropertiesFactoryBean 会将 YAML 加载为 Properties,YamlMapFactoryBean 会将YAML 加载为 Map。
例如:如果我们存在下面的 YAML 文档,我们分别使用 YamlPropertiesFactoryBean 和 YamlMapFactoryBean 进行解析。
(1)创建 demo1.yml 文档,YAML 文档内容如下:
environments: dev: url: http://dev.bar.com name: Developer Setup prod: url: http://foo.bar.com name: My Cool App
(2)使用 YamlPropertiesFactoryBean 解析 YAML 文档,如下:
public void loadFile(){ // 1.获取 yml 文件资源 Resource resource = new ClassPathResource("demo1.yml"); // 2.解析 yml 文件 YamlPropertiesFactoryBean bean = new YamlPropertiesFactoryBean(); bean.setResources(resource); // 3.读取解析结果 Properties prop = bean.getObject(); for(Object key : prop.keySet()) { System.out.println(key + " = " + prop.get(key)); } }
输出结果如下:
environments.dev.name = Developer Setup environments.prod.name = My Cool App environments.prod.url = http://foo.bar.com environments.dev.url = http://dev.bar.com
(3)使用 YamlMapFactoryBean 解析 YAML 文档,如下:
public void loadFile(){ // 1.获取 yml 文件资源 Resource resource = new ClassPathResource("demo1.yml"); // 2.解析 yml 文件 YamlMapFactoryBean bean = new YamlMapFactoryBean(); bean.setResources(resource); // 3.读取解析结果 Map<String,Object> map = bean.getObject(); System.out.println(JSON.toJSONString(map, true)); }
输出结果如下:
{ "environments":{ "dev":{ "url":"http://dev.bar.com", "name":"Developer Setup" }, "prod":{ "url":"http://foo.bar.com", "name":"My Cool App" } } }
YAML 列表被 YamlPropertiesFactoryBean 进行解析,属性 key 表示成使用 [index] 间接引用形式。例如下面的 YAML:
my: servers: - dev.bar.com - foo.bar.com
如果使用 YamlPropertiesFactoryBean 进行解析,输出如下:
my.servers[0] = dev.bar.com my.servers[1] = foo.bar.com
如果使用 YamlMapFactoryBean 进行解析,输出如下:
{ "my":{ "servers":[ "dev.bar.com", "foo.bar.com" ] } }
使用 Spring DataBinder 工具集绑定这些属性(这是 @ConfigurationProperties 做的事)时,你需要确保目标 bean 有个 java.util.List 或 Set 类型的属性,并且需要提供一个 setter 或使用可变的值初始化它。例如:下面的代码将绑定上面的 my.servers 属性:
@ConfigurationProperties(prefix = "my") @Component public class Config { // 自动将 YAML 中的 servers 项加载到该成员变量 private List<String> servers = new ArrayList<>(); public void setServers(List<String> servers) { this.servers = servers; } public void loadFile() { System.out.println(JSONObject.toJSONString(servers, true)); } }
输出结果如下:
[ "dev.bar.com", "foo.bar.com" ]
YamlPropertySourceLoader 类能够将 YAML 作为 PropertySource 导出到 Sprig Environment,这将允许你使用常用的 @Value 注解配合占位符(例如:${})语法访问 YAML 属性。
你可以在单个 YAML 文件中定义多个特定 Profile 的配置(profile-specific),并通过 spring.profiles.active 配置使某个特定配置生效,例如:
spring: profiles: active: dev server: address: 192.168.1.100 --- spring: profiles: dev server: address: 127.0.0.1 --- spring: profiles: prod server: address: www.hxstrive.com
在以上例子中,如果 dev profile 被激活,server.address 属性将是 127.0.0.1 ;如果 dev 和 prod profiles 均没有启用,则该属性的值将是 192.168.1.100 。
在应用上下文启动时,如果没有明确指定激活的 profiles,则默认的 profiles 将生效。所以,在下面的文档中我们提供了一个名为 default 的 profiles,该 profile 中 server.address = localhost。如下:
--- spring: profiles: default server: address: localhost --- spring: profiles: dev server: address: 127.0.0.1 --- spring: profiles: prod server: address: www.hxstrive.com
在上面例子中,我们没有显示激活任何 profiles,将应用默认的(即 default)profiles。
注意:YAML 文件不能通过 @PropertySource 注解加载,如果需要使用该方式,那就必须使用 properties 文件。