欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-04 11:24:12
灵魂拷问:YAML,在项目中用过没?它与 properties 文件啥区别? 目前 SpringBoot、SpringCloud、Docker 等各大项目、各大组件,在使用过程中几乎都能看到 YAML 文件的身影。 2017 年的时候,我才真正把 YAML 文件用到负责的项目中,当时用 YAML 文 ......

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

目前 springboot、springcloud、docker 等各大项目、各大组件,在使用过程中几乎都能看到 yaml 文件的身影。

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

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

 

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

 

1. 初步感受 yaml 的魅力。

 

细数Java项目中用过的配置文件(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/

细数Java项目中用过的配置文件(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 函数,发现解析代码没几行,跑起来看一看,效果还可以。

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

 

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

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

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

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

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

 

3. 它山之石可以攻玉

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

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