Spring Boot 教程

使用 YAML 代替 Properties

Spring Boot 不仅仅支持 Properties(.properties)属性配置文件,还支持 YAML(.yml)配置文件。

YAML 是 JSON 的一个超集,也是一种方便配置层次结构数据的格式。只要你将 SnakeYAML 库放到 classpath 下, Spring 应用就会自动支持 YAML,以作为 Properties 属性文件的替换。

注意:如果你的应用使用了 ”Starters“,且添加了 spring-boot-starter 依赖,则会自动加载 SnakeYAML 库。

加载 YAML

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 文件。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号