转载

微服务系列:你真的懂 Yaml 吗?

在Java 的世界里,配置的事情都交给了 Properties,要追溯起来这个模块还是从古老的JDK1.0 就开始了的。

"天哪,这可是20年前的东西了,我居然还在用 Properties.."

微服务系列:你真的懂 Yaml 吗?

然而,本文的主角并不是Properties,而是Yaml。

这是新时代里微服务架构上的宠儿,和 Properties 相比起来,Yaml 显得有些弄潮儿。以往的大多数项目里,我们都可以发现 Properties配置文件的踪迹,这包括用作 业务属性配置的、机机接口交互的、国际化的等等用途。而少量的一些情况下,也存在一些"混合式"的做法,比如:

  • 使用 Xml 来表示一些模板

  • 使用一个 Json 格式化的字符串

  • 裸奔的文本格式,应用自解析 ...

混杂的配置方式往往出现在 一些充满"坏味道" 的项目里头,因为代码陈旧、斯人已矣 等原因,很难形成统一的方式。然而,除开 Properties 属性文件这种简单的配置方式之外,采用其他的方法不外乎都是为了适应配置复杂、多元化的诉求。

那么,Yaml 就是应对这种场景而产生的,在 SpringBoot 的官方文档中,有不少篇幅是 使用了 Yaml 语法的配置格式。 下面介绍一下 Yaml 以及它是如何使用的。

一、什么是 Yaml

来自百科的定义:

"Yaml 是一个可读性高,易用的数据序列化格式,由 Clark Evans 在2001年首次发表。"

可见 Yaml 并不是一个很新的东西,只是在以前接触的人不多罢了。 此外,Yaml也被各种编程语言及框架所支持, 通用性很高。 在Java体系中,一般的微服务框架都支持甚至优先推荐使用 Yaml 作为首选的配置语言。

而 Yaml 本身具有什么特点? 看看下面的一个实例:

这段语法等价的 Properties 为:

可见, yaml 相对来说更加的结构化,更适合用来表达一个对象。 它在语法上有这样的特点:

  • 大小写敏感

  • 使用空格缩进表示层级关系,摒弃使用Tab键, 这主要是考虑到不同平台上文本展现时需要对齐

  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

  • 使用 # 开头作为注释行

  • 使用 连接符(-)开头来描述数组元素

对比 Properties

Properties 可以很好的实现 Key-Value 的配置,包括作为一些国际化内容的配置方式。但 Properties 很难表现多层级的嵌套关系,此时如果用 Yaml 可以较好的弥补该短板。

对比 Json

Yaml 与 Json本身没有太多的优劣之分,两者都是结构化的表达式语言,但是Json的设计重点在于  简单易用、方便传输   的特性;而 Yaml 则侧重于 可读性(更加在乎外观) ,几乎可以把 Yaml 看做是 Json 的一个"超集",即可读性更高(更漂亮) 的结构化格式。

此外,Json更加便于生成和解析,适合在各种跨语言、分布式的环境中传输和交互;与此同时, Yaml 则一般只是用作的配置较多。

关于 Yaml 的定义可以访问下面的地址:

http://www.yaml.org/spec/1.2/spec.html

二、Yaml 的语法

Yaml 是非常精简的, 它所定义的元素只有三个:

  • 对象:就是键值对的集合,对应于Java 中的 HashMap

  • 数组:指一组按序排列的值,对应于Java 中的 List

  • 单值:单个的、不可再分的值,比如 3,"Jackson"

对象如何表示

一个对象的属性、嵌套关系通过空格缩进对齐来表示,如下:

数组如何表示

数组的元素通过连接符(-)来表示,如下:

构成对象、数组内容的基本单元是单值,Yaml支持的单个值的类型有七种,如下:

类型 范例
字符串 Bob
布尔值 true
整数 199
浮点数 19.91
Null ~
时间 2001-12-14T22:14:09.10+08:00
日期 2019-01-09

其中,日期、时间使用的是 ISO 8601 国际标准格式,关于它的定义可以参考: https://www.w3.org/TR/NOTE-datetime

一般情况下单个值会在一行内结束。 但如果遇到多行的字符串,可以使用一些特殊字符表示, 比如:

对应的结果为:

可以用 + 表示保留字符串末尾的换行, - 表示删除字符串末尾的换行:

对应的结果为:

除此之外,Yaml 还可以支持引用、函数、正则表达式等高级用法,但项目上一般很少用到。

三、操作 Yaml

微服务系列:你真的懂 Yaml 吗?

目前用来操作 Yaml 的常用组件是 Snake Yaml,这个库支持标准的 Yaml 1.1 版本

SpringBoot 官方文档也介绍了整合该框架的方式,参考下面的地址: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml

下面提供 将SnakeYaml 整合到项目的样例。

A. 引入框架

在Maven的pom.xml文件中添加:

B. 代码片段

实现加载配置文件

如下面的代码,实现了从类路径config.yml文件中加载 yaml 配置内容:

实现对象转换

定义如下的Pojo 对象:

通过 SnakeYaml 将对象输出为 Yaml 格式的代码:

输出结果如下:

此时如果希望将Yaml 文本反过来转换为 A 对象,可以执行下面的代码:

C. 完整案例

最终,我们可以将 Yaml 文档的操作封装为一个工具类,方便在业务代码中集成。

YamlUtil.java

至此,我们已经完成了 Yaml 的读写。当然,除了上述的 Snake Yaml 之外,还可以使用 流行的 Jackson 组件来完成类似功能,这里不再过多赘述,有兴趣的朋友可以自行尝试。

参考文档

阮一峰-YAML语言教程:

http://www.ruanyifeng.com/blog/2016/07/yaml.html

SnakeYaml 官方文档:

https://bitbucket.org/asomov/snakeyaml/wiki/Documentation

Yaml 1.2 规范:

http://www.yaml.org/spec/1.2/spec.html

SpringBoot-LoadingYaml

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-loading-yaml

点击查看美码师的 SpringBoot 补习系列

原文  https://mp.weixin.qq.com/s?__biz=MzAwNjY3MjgzOA==&mid=2477610592&idx=1&sn=751e1504d23905f9a5e8495828988cfb&chksm=8d502ec9ba27a7df5328994c3811e6faf0c699efa5055c175a4c1648144ce4840ae669ea685d&token=1524446375&lang=zh_CN
正文到此结束
Loading...