细数Java项目中用过的配置文件(YAML篇)
灵魂拷问: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篇)的更多相关文章
- 细数Java项目中用过的配置文件(ini 篇)
Java 菜鸟,会把可变的配置信息写死在代码里:Java 老鸟,会把可变的配置信息提取到配置文件中.坊间流传这么一句非科学的衡量标准,来评判程序员的级别. 那么,项目中的配置信息,你平时都是怎样来实现 ...
- java项目部署之后,Jar包中配置文件修改
Java项目发布时,配置文件不像.net项目一样与工程路径保持一致,而是直接包含在了jar包中,此时要修改就没那么方便了,我们可以将配置文件从jar包抽离出来,修改完之后再写入Jar包即可, 也没那么 ...
- LinkedHashMap和HashMap的比较使用 由于现在项目中用到了LinkedHashMap,并不是太熟悉就到网上搜了一下。 ? import java.util.HashMap; impo
LinkedHashMap和HashMap的比较使用 由于现在项目中用到了LinkedHashMap,并不是太熟悉就到网上搜了一下. import java.util.HashMap; import ...
- 转载:Java项目读取配置文件时,FileNotFoundException 系统找不到指定的文件,System.getProperty("user.dir")的理解
唉,读取个文件,也就是在项目里面去获得配置文件的目录,然后,变成文件,有事没事,总是出个 FileNotFoundException 系统找不到指定的文件,气死人啦. 还有就是:System.get ...
- 统计Java项目的代码行数
Java项目谈论行数多少有点无聊,但是有的时候就想看看一个开源的代码的量级,用Shell命令统计再合适不过了 去掉空行和注释: find . -name "*.java" |xar ...
- 细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一
细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一(转) ADO.NET Entity Framework ADO.NET Entity Framework 是微软以 ADO.N ...
- java项目——数据结构实验报告
java项目——数据结构总结报告 20135315 宋宸宁 实验要求 1.用java语言实现数据结构中的线性表.哈希表.树.图.队列.堆栈.排序查找算法的类. 2.设计集合框架,使用泛型实现各类. ...
- Java学习-007-Log4J 日志记录配置文件详解及实例源代码
此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:20 ...
- Java项目打包在CMD或者Linux下运行
Java项目打包在CMD或者Linux下运行 1.在CMD下运行 在eclipse中将项目export成jar包,然后用压缩软件解压
随机推荐
- XiaoQi.Study项目(一)
项目地址:https://github.com/xiaoqiyaozou1/XiaoQi.Study 感谢:“老张的哲学”.“晓晨”.“杨旭”等大佬的知识分享 一.项目创建 vs 2019 创建 as ...
- iview admin template 基础模板架子
https://github.com/iview/iview-admin/tree/template
- oracle --游标详解(转)
转自:http://blog.csdn.net/liyong199012/article/details/8948952 游标的概念: 游标是SQL的一个内存工作区,由系统或用户以变量的形式定 ...
- 安卓App自动化测试环境
一.appium安装 1.nodejs依赖 2..net framework 3.Appium桌面程序安装 3.1.安装包获取 3.2.安装过程 二.Java_ jdk安装 1.Java_jdk版本说 ...
- Natas26 Writeup(PHP反序列化漏洞)
Natas26: 打开页面是一个输入坐标点进行绘图的页面. <html> <head> <!-- This stuff in the header has nothing ...
- python如何通过正则表达式一次性提取到一串字符中所有的汉字
1.python如何通过正则表达式一次性提取到一串字符中所有的汉字 https://blog.csdn.net/py0312/article/details/93999895 说明:字符串前的 “ r ...
- Ruby中的Hash(哈希),你可以理解为字典
原文链接 以下代码在Ruby 2.5.1中编译通过 定义 myHash = Hash.new myHash1 = Hash["key1" => 100, "key2 ...
- C 2014年笔试题
1.指出程序中的错误,说明原因并修正 int *p,*q; p=malloc(sizeof(int)*20); q=malloc(sizeof(int)*10); … q=p; … free(p); ...
- [Linux系统] CentOS7(RHEL7)重置root用户密码
1.系统启动时,按"e"进入编辑界面 2.编辑内容 将rhgb quiet修改为 init=/bin/sh : 然后按 ctrl+x . 3.修改root密码 mount -o r ...
- HTTP、TCP、IP协议面试题
HTTP.TCP.IP协议基本定义 HTTP: (HyperText Transport Protocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2 ...