Y服务-你真的懂 Yaml 吗
目录
在Java 的世界里,配置的事情都交给了 Properties,要追溯起来这个模块还是从古老的JDK1.0 就开始了的。
然而,本文的主角并不是Properties,而是Yaml。这是新时代里微服务架构上的宠儿,和 Properties 相比起来,Yaml 显得有些弄潮儿。
混杂的配置方式往往出现在一些充满"坏味道"的项目里头,因为代码陈旧、斯人已矣 等原因,很难形成统一的方式。 那么,Yaml 就是应对这种场景而产生的,在 SpringBoot 的官方文档中,有不少篇幅是 使用了 Yaml 语法的配置格式。 一、什么是 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 相对来说更加的结构化,更适合用来表达一个对象。
对比 Properties 对比 Json 关于 Yaml 的定义可以访问下面的地址: 二、Yaml 的语法Yaml 是非常简单的, 它所定义的元素只有三个:
对象如何表示 article: title: 一个人的自白书 author: name: 陈玲 gender: female 数组如何表示 article: title: 一个人的自白书 tags: - 传记 - 社会 - 人物 构成对象、数组内容的基本单元是单值,Yaml支持的单个值的类型有七种,如下:
其中,日期、时间使用的是 ISO 8601 国际标准格式,关于它的定义可以参考: 一般情况下单个值会在一行内结束。但如果遇到多行的字符串,可以使用一些特殊字符表示, text: | Hello World 对应的结果为: { text: 'HellonWorldn' } 可以用+表示保留字符串末尾的换行,-表示删除字符串末尾的换行: text1: |+ Hello text2: |- Hello 对应的结果为: { text1: 'Hellonnn',text2: 'Hello' } 除此之外,Yaml 还可以支持引用、函数、正则表达式等高级用法,但项目上一般很少用到。 三、操作 Yaml目前用来操作 Yaml 的常用组件是 Snake Yaml,这个库支持标准的 Yaml 1.1 版本。 SpringBoot 官方文档也介绍了整合该框架的方式,参考下面的地址: 下面提供 将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语言教程: SnakeYaml 官方文档: Yaml 1.2 规范: SpringBoot-LoadingYaml 点击查看美码师的 SpringBoot 补习系列 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |