灵魂拷问:YAML,在项目中用过没?它与 properties 文件啥区别?

目前 SpringBoot、SpringCloud、Docker 等各大项目、各大组件,在使用过程中几乎都能看到 YAML 文件的身影。

2017 年的时候,我才真正把 YAML 文件用到负责的项目中,当时用 YAML 文件主要是为 Sharding-JDBC 配置数据源以及分库分表的规则。

从实际项目中把 sharding-jdbc.yaml 文件抽出来,为了更清晰,进行了大量简化,接下来就一同感受一下 YAML 的魅力

1. 初步感受 YAML 的魅力。

上图配置的内容虽然还没解释,仔细去看配置,大体都能看明白。其实,这就是 YAML 比 properties 配置文件的优势所在,层次感分明,配置有序,而且比较简洁。

纵然配置已经很清晰,还是要稍微带着看一看配置内容。

dev 是一个对象,对应于 Java 中的 Map,包含 datasources 和 tables 两个属性。其本身含义是开发环境配置,当然实际项目中也会有测试、准生产、生产的对应的配置。

datasources 属性是一个数组,对应于 Java 中的 List,数组元素由 name、default 等 10 个属性构成。其本身含义是数据源配置,因为涉及到分库,所以会有好多库要连接,图中只列举两个数据库;

tables 属性也是一个数组,对应于 Java 中的 List,数组元素由 tableName、databaseCount 等 5 个属性构成。其本身含义是要拆分表的规则配置,图中只列举一个项目基本信息表。

按照常规思路,写好配置文件,接下来就要校验一下,再稍微格式化一下。

在这儿校验Yaml文件:http://www.bejson.com/validators/yaml/

如上图所示,YAML 文件校验转换之后,就真的太清晰啦!

不过,YAML 是很简单,但是有些细节,在开发中还是要注意,否则入坑就难跳出(一旦入坑,真的不好跳出来,别问为什么?一个空格难倒英雄汉,真心体会过)。

Tips:

1. 使用冒号加缩进的方式代表层级关系,使用短横杠代表数组元素;

2. 注意缩进不允许使用「tab」键,只能使用空格键(曾经掉这个坑啦,记忆之深刻);

3. 缩进空格个数多少并不重要,只要相同层级的元素左对齐即可;

4. 如果冒号后跟着 value,一定要注意冒号后跟上空格呦!

5. YAML 大小写很敏感。

有关 YAML 的更多规范,可以参考如下 pdf,本次不过多展开去讲。

https://yaml.org/spec/1.2/spec.pdf

2. YAML 配置有了,该怎么去解析呢?

在不同的编程语言中,都有很多三方工具可以解析 YAML 文件,而在 Java 项目可以用 SnakeYaml 进行解析,接下来就写写代码体验一下 yaml 文件的解析。

首先引入依赖包(想用人家,就别想撇清关系!)

<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.18</version>
</dependency>

码点代码(从原项目中直接拿来,为了清晰,索性只留解析 YAML 文件部分的代码,呈现给你)

import org.apache.commons.collections4.MapUtils;
import org.yaml.snakeyaml.Yaml; import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map; /**
* @author 一猿小讲
*/
public class ShardingJdbcDataSource {
private static LinkedHashMap<String, Object> profile; @SuppressWarnings("unchecked")
public static ArrayList<LinkedHashMap<String, Object>> parse(String profileId, String key) throws IOException {
//如果profile为空的情况才进行加载配置文件,减少读取文件的次数
if (MapUtils.isEmpty(profile)) {
Yaml yaml = new Yaml();
File file = new File(ShardingJdbcDataSource.class.getResource("/").getPath() + "sharding-jdbc.yaml");
try (FileReader fileReader = new FileReader(file);) {
Map<String, Object> result = yaml.loadAs(fileReader, Map.class);
profile = (LinkedHashMap<String, Object>) result.get(profileId);
}
}
return (ArrayList<LinkedHashMap<String, Object>>) profile.get(key);
} public static void main(String[] args) throws IOException {
// 开发环境
String profileId = "dev"; // 数据源集合
ArrayList<LinkedHashMap<String, Object>> datasources = parse(profileId, "datasources");
for (LinkedHashMap<String, Object> datasource : datasources) {
System.out.println(String.format("数据库名称:%s",datasource.get("name")));
System.out.println(String.format("数据库URL:%s",datasource.get("jdbc.url")));
} System.out.println("=============华丽的分割线=============="); // 表集合
ArrayList<LinkedHashMap<String, Object>> tables = parse(profileId, "tables");
for (LinkedHashMap<String, Object> table : tables) {
System.out.println(String.format("表名称:%s",table.get("tableName")));
System.out.println(String.format("数据库拆分 %d 个",table.get("databaseCount")));
System.out.println(String.format("每个数据库表的数目:%s",table.get("tableCountPerDatabase")));
}
}
}

去掉 main 函数,发现解析代码没几行,跑起来看一看,效果还可以。

文中的解析 YAML 文件的代码,改个类名,就可以直接变成工具类,如果有需要,自行简单封装一下就 ok 啦。

其中 SnakeYaml 类库还有很多 API 可以使用,不一一带着写代码啦,感兴趣的自行参考 SnakeYaml 官方文档,去照猫画虎敲敲吧。

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

另外,细心的你在平时研发时,有没有发现,有的项目 YAML 文件的后缀是 .yml,有的项目却是 .yaml,到底哪个是正确的呢?很久很久之前我也纠结过,感兴趣可以去 stackoverflow 溜达一番。

https://stackoverflow.com/questions/21059124/is-it-yaml-or-yml

3. 它山之石可以攻玉

在 Java 项目研发过程中,总会遇到一些经常改变的参数,比如要连接的数据库的连接地址、名称、用户名、密码;再比如访问三方服务的 URL 等等。考虑到程序的通用性,这些参数往往不能直接写死在程序里,通常借助配置文件来优雅处理,而常用的配置文件多数为 Properties,而相对 Properties 而言 YAML 却表现的更加层次分明。

好了,有关 YAML 文件在实际项目中的使用,本次就谈到这里,它山之石可以攻玉,希望能对你有所帮助。

细数Java项目中用过的配置文件(YAML篇)的更多相关文章

  1. 细数Java项目中用过的配置文件(ini 篇)

    Java 菜鸟,会把可变的配置信息写死在代码里:Java 老鸟,会把可变的配置信息提取到配置文件中.坊间流传这么一句非科学的衡量标准,来评判程序员的级别. 那么,项目中的配置信息,你平时都是怎样来实现 ...

  2. java项目部署之后,Jar包中配置文件修改

    Java项目发布时,配置文件不像.net项目一样与工程路径保持一致,而是直接包含在了jar包中,此时要修改就没那么方便了,我们可以将配置文件从jar包抽离出来,修改完之后再写入Jar包即可, 也没那么 ...

  3. LinkedHashMap和HashMap的比较使用 由于现在项目中用到了LinkedHashMap,并不是太熟悉就到网上搜了一下。 ? import java.util.HashMap; impo

    LinkedHashMap和HashMap的比较使用 由于现在项目中用到了LinkedHashMap,并不是太熟悉就到网上搜了一下. import java.util.HashMap; import ...

  4. 转载:Java项目读取配置文件时,FileNotFoundException 系统找不到指定的文件,System.getProperty("user.dir")的理解

    唉,读取个文件,也就是在项目里面去获得配置文件的目录,然后,变成文件,有事没事,总是出个 FileNotFoundException  系统找不到指定的文件,气死人啦. 还有就是:System.get ...

  5. 统计Java项目的代码行数

    Java项目谈论行数多少有点无聊,但是有的时候就想看看一个开源的代码的量级,用Shell命令统计再合适不过了 去掉空行和注释: find . -name "*.java" |xar ...

  6. 细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一

    细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一(转) ADO.NET Entity Framework        ADO.NET Entity Framework 是微软以 ADO.N ...

  7. java项目——数据结构实验报告

    java项目——数据结构总结报告 20135315  宋宸宁 实验要求 1.用java语言实现数据结构中的线性表.哈希表.树.图.队列.堆栈.排序查找算法的类. 2.设计集合框架,使用泛型实现各类. ...

  8. Java学习-007-Log4J 日志记录配置文件详解及实例源代码

    此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:20 ...

  9. Java项目打包在CMD或者Linux下运行

    Java项目打包在CMD或者Linux下运行 1.在CMD下运行 在eclipse中将项目export成jar包,然后用压缩软件解压

随机推荐

  1. 搭建Java开发环境之配置环境变量

    前言 初学Java不久的二胖在搭建Java开发环境一步就遇到问题,他不由得感叹:万事开头难啊!但感叹之后它还是鼓足了劲去努力解决它,二胖在电脑上Google了一番,最终环境是搭建成功了,但他心中对&q ...

  2. MySQL 统计行数的 count

    MySQL count() 函数我们并不陌生,用来统计每张表的函数.但如果你的表越来越大,并且是 InnoDB 引擎的话,会发现计算的速度会越来越慢.在这篇文章里,会先介绍 count() 实现的原理 ...

  3. apply 和 call 方法详解【转载】

    本文转载至:http://blog.csdn.net/business122/article/details/8000676 我在一开始看到javascript的函数apply和call时,非常的模糊 ...

  4. Python 之装饰器

    Python 的装饰器可谓是提高开发效率的一大利器.然而初学装饰器的时候感觉很难理解,因为除了 Python 之外没听说哪个语言有这种东西. 而且网上看的很多解释看似容易理解,但只能很快理解了装饰器能 ...

  5. 3D游戏中各种空间变换到底是怎么回事

    每一个游戏可以呈现炫丽效果的背后,需要进行一系列的复杂计算,同时也伴随着各种各样的顶点空间变换.渲染游戏的过程可以理解成是把一个个顶点经过层层处理最终转化到屏幕上的过程,本文就旨在说明,顶点是经过了哪 ...

  6. 基于.NetCore3.1搭建项目系列 —— 使用Swagger做Api文档 (下篇)

    前言 回顾上一篇文章<使用Swagger做Api文档 >,文中介绍了在.net core 3.1中,利用Swagger轻量级框架,如何引入程序包,配置服务,注册中间件,一步一步的实现,最终 ...

  7. 2. weddriver的定位方法

    一. find_element_by_****的方式 首页在网页上鼠标右键选择检查并点击,查看需要定位的元素. https://www.baidu.com  以百度为例 导入模块的: from sel ...

  8. jwt token认证

    目录 1.drf-jwt手动签发与校验 2.drf小组件:过滤.筛选.排序.分页 => 针对与群查接口 jwt_token源码分析(入口) 签发token源码分析 校验token源码分析 url ...

  9. [ICRA 2019]Multi-Task Template Matching for Object Detection, Segmentation and Pose Estimation Using Depth Images

    简介         本文作者提出新的框架(MTTM),使用模板匹配来完成多个任务,从深度图的模板上找到目标物体,通过比较模板特征图与场景特征图来预测分割mask和模板与检测物体之间的位姿变换.作者提 ...

  10. [gcd,灵感] Codeforces 1200C Round Corridor

    题目:https://codeforces.com/contest/1200/problem/C C. Round Corridor time limit per test 1 second memo ...