Y服务-你真的懂 Yaml 吗?
在Java 的世界里,配置的事情都交给了 Properties,要追溯起来这个模块还是从古老的JDK1.0 就开始了的。
"天哪,这可是20年前的东西了,我居然还在用 Properties.."
然而,本文的主角并不是Properties,而是Yaml。这是新时代里微服务架构上的宠儿,和 Properties 相比起来,Yaml 显得有些弄潮儿。
以往的大多数项目里,我们都可以发现 Properties配置文件的踪迹,这包括用作业务属性配置的、机机接×××互的、国际化的等等用途。
而少量的一些情况下,也存在一些"混合式"的做法,比如:
- 使用 Xml 来表示一些模板
- 使用一个 Json 格式化的字符串
- 裸奔的文本格式,应用自解析
...
混杂的配置方式往往出现在一些充满"坏味道"的项目里头,因为代码陈旧、斯人已矣 等原因,很难形成统一的方式。
然而,除开 Properties 属性文件这种简单的配置方式之外,采用其他的方法不外乎都是为了适应配置复杂、多元化的诉求。
那么,Yaml 就是应对这种场景而产生的,在 SpringBoot 的官方文档中,有不少篇幅是 使用了 Yaml 语法的配置格式。
下面介绍一下 Yaml 以及它是如何使用的。
一、什么是 Yaml
来自百科的定义:
"Yaml 是一个可读性高,易用的数据序列化格式,由 Clark Evans 在2001年首次发表。"
可见 Yaml 并不是一个很新的东西,只是在以前接触的人不多罢了。此外,Yaml也被各种编程语言及框架所支持, 通用性很高。
在Java体系中,一般的微服务框架都支持甚至优先推荐使用 Yaml 作为首选的配置语言。
而 Yaml 本身具有什么特点? 看看下面的一个实例:
environments: dev: url: https://dev.example.com name: Developer Setup prod: url: https://another.example.com name: My Cool App
这段语法等价的 Properties 为:
environments.dev.url=https://dev.example.com environments.dev.name=Developer Setup environments.prod.url=https://another.example.com environments.prod.name=My Cool App
可见, 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"
对象如何表示
一个对象的属性、嵌套关系通过空格缩进对齐来表示,如下:
article: title: 一个人的自白书 author: name: 陈玲 gender: female
数组如何表示
数组的元素通过连接符(-)来表示,如下:
article: title: 一个人的自白书 tags: - 传记 - 社会 - 人物
构成对象、数组内容的基本单元是单值,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
一般情况下单个值会在一行内结束。但如果遇到多行的字符串,可以使用一些特殊字符表示,
比如:
text: | Hello World
对应的结果为:
{ text: 'Hello\nWorld\n' }
可以用+表示保留字符串末尾的换行,-表示删除字符串末尾的换行:
text1: |+ Hello text2: |- Hello
对应的结果为:
{ text1: 'Hello\n\n\n', text2: 'Hello' }
除此之外,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文件中添加:
<dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.21</version> </dependency>
B. 代码片段
实现加载配置文件
如下面的代码,实现了从类路径config.yml文件中加载 yaml 配置内容:
InputStream inputStream = YamlUtil.class.getClassLoader() .getResourceAsStream("config.yml"); Yaml yaml = new Yaml(); Map<String, Object> objectMap = yaml.load(inputStream); System.out.println(objectMap.get("path"));
实现对象转换
定义如下的Pojo 对象:
public static class A{ private String name = "hello"; private List<B> bs = new ArrayList<B>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public List<B> getBs() { return bs; } public void setBs(List<B> bs) { this.bs = bs; } } public static class B{ private String id = UUID.randomUUID().toString(); public String getId() { return id; } public void setId(String id) { this.id = id; } }
通过 SnakeYaml 将对象输出为 Yaml 格式的代码:
A a = new A(); a.getBs().add(new B()); a.getBs().add(new B()); Yaml yaml = new Yaml(); String aString = yaml.dumpAsMap(a); System.out.println(aString);
输出结果如下:
bs: - id: b3688f05-ea7e-436b-bc9a-9c5df555c7fd - id: 7906224d-8ecc-43b8-bc3b-07985bc18ebd name: hello
此时如果希望将Yaml 文本反过来转换为 A 对象,可以执行下面的代码:
A a1 = new Yaml().parseToObject(aString, A.class); ...
C. 完整案例
最终,我们可以将 Yaml 文档的操作封装为一个工具类,方便在业务代码中集成。
YamlUtil.java
public class YamlUtil { /** * 从资源文件加载内容,并解析为Map对象 * * @param path * @return */ public static Map<String, Object> loadToMap(String path) { if (StringUtils.isEmpty(path)) { return Collections.emptyMap(); } InputStream inputStream = YamlUtil.class.getClassLoader() .getResourceAsStream(path); Yaml yaml = new Yaml(); Map<String, Object> objectMap = yaml.load(inputStream); return objectMap; } /** * 将字符串解析为Map对象 * * @param content * @return */ public static Map<String, Object> parseToMap(String content) { if (StringUtils.isEmpty(content)) { return Collections.emptyMap(); } Yaml yaml = new Yaml(); Map<String, Object> objectMap = yaml.load(content); return objectMap; } /** * 将字符串解析为类对象 * * @param content * @param clazz * @param <T> * @return */ public static <T> T parseToObject(String content, Class<T> clazz) { if (StringUtils.isEmpty(content) || clazz == null) { return null; } Yaml yaml = new Yaml(new Constructor(clazz)); T object = yaml.load(content); return object; } /** * 格式化对象 * * @param object * @return */ public static String format(Object object) { Yaml yaml = new Yaml(); return yaml.dumpAsMap(object); } }
至此,我们已经完成了 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
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Hyper-v 实现桌面虚拟化
为了方便对公司办公机桌面系统进行管理,所以需要 Hyper-v 虚拟化平台对桌面进行部署。Hyper-v 是微软的一款虚拟化产品,是微软第一个采用 VMware 和 Citrix 一样的基于 hypervisor 的技术。 Hyper-v 角色可以利用内置于 Windows server 中的虚拟化技术创建和管理虚拟化的计算机环境。 Hyper-v 所需组件: Windows 虚拟机监控程序; Hyper-v 虚拟机管理服务; 虚拟化 WMI 提供程序; 其他虚拟化组件; Hyper-v 需要一个64位处理器,需要具有 Intel 虚拟化技术(Intel VT)或 AMD (AMD-V)技术的处理器。要求硬件强制实施的数据执行保护(DEP)必须可用且已启用,也就是必须启用 Intel XD (执行禁用位)或 AMD NX 位(无执行位)由于服务器上要运行虚拟机,建议在实际生产环境中的资源配置应该适度调节!案例环境:首先将DC配置好,需要添加DHCP、DNS服务,新建每一个DHCP的作用域,为虚拟机提供IP,Remote Desktop 主机需要加入域中。(DHCP、DNS服务在前面文章...
- 下一篇
python股票市场数据探索指北
前言 虽然同花顺之类的金融理财应用的数据足够好了,但还是有自己定制的冲动, 数据自然不会不会比前者好很多,但是按照自己的想法来定制还是不错的。 目标 通过免费的数据接口获取数据,每日增量更新标的历史交易数据, 然后通过Kibana做可视化及数据分析. 其实自己通过echarts之类的可视化框架做可视化也是个不错的选择,不过前期成本太大。还有就是pandas+matplotlib已经足以应付大部分需求了,可是交互感太弱,所以借助一个可视化应用是很有必要的,这里选择的是kibana, 它的竞品有Grafana. 这个目标应该会一直下去吧,大家可以通过以下链接获取代码 https://github.com/youerning/stock_playground 环境配置 Python3(推荐Anaconda安装) 安装相关依赖: pip install -r requirement.txt 配置eleasticsearch, kibana环境(推荐使用docker) Elasticsearch, Logstash, Kibana 7.2.0 数据源 获取数据的方式有很多种,收费或者免费,作为业...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS6,CentOS7官方镜像安装Oracle11G
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作