灵魂拷问: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. 关于SDL的一些坑:找不到WinMain,不显示控制台,添加链接库等

    目录: 用CMake构建SDL时报错 Gcc添加链接库 Gcc找不到入口(WinMain) 让SDL启动时不带控制台窗口 用CMake构建SDL时报错 root@ubuntu:~/SDL# cmake ...

  2. layui的form表单的checkbox全选与全不选问题

    <!DOCTYPE html> <html> <head>     <meta charset="utf-8">     <m ...

  3. 神器cut基因剪

    cut cut 不就是切嘛,没错就是它--我给他起了一个外号基因剪刀 来我们学一下怎么使用这个命令 cut --help [root@ESProbe ~]# cut --help Usage: cut ...

  4. Java抽象类和接口的区别及联系

    抽象类 注:先将抽象类中的两种方法解释完,再综合解释抽象类 抽象方法 应用场景:其下所有子类都应该有该方法但是大部分子类具体的执行步骤是有所不同的. 必须重写:也可以说"必须实现" ...

  5. mysql锁机制和事务隔离

    mysql事务 1.InnoDB事务原理 事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. 在数据库提交时,可以确保要么所有修 ...

  6. Linux常用命令 - top命令详解(重点)

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html top ...

  7. Swift 4.0 数组(Array)之过滤器(filter)的使用

    我们先来定义一个常量整型数组 let array = [5, 4, 3, 1, 2] 过滤器(filter)使用之筛选出大于3的值 let resultArray = array.filter { ( ...

  8. Redhat 线下赛 WEB WP

    赛制 给每个参赛队伍所有题目的gamebox,参赛队伍在开赛时就能获取到所有题目的源码,可以选择先防御后攻击或先攻击后防御,只要拿到gamebox上的flag,机器人就会自动帮你攻击场上所有未防御选手 ...

  9. 泛微E-cology OA 远程代码执行漏洞

    分析文章:https://dwz.cn/bYtnsKwa http://127.0.0.1/weaver/bsh.servlet.BshServlet 若存在如上页面,则用下面数据包进行测试. POS ...

  10. vue基础指令学习

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...