細數Java項目中用過的配置文件(YAML篇)

YAML,在項目中用過沒?它與 properties 文件啥區別?


目前 SpringBoot、SpringCloud、Docker 等各大項目、各大組件,在使用過程中幾乎都能看到 YAML 文件的身影。


2017 年的時候,我才真正把 YAML 文件用到負責的項目中,當時用 YAML 文件主要是為 Sharding-JDBC 配置數據源以及分庫分表的規則。


細數Java項目中用過的配置文件(YAML篇)

初步感受 YAML 的魅力

從實際項目中把 sharding-jdbc.yaml 文件抽出來,為了更清晰,進行了大量簡化,接下來就一同感受一下 YAML 的魅力


細數Java項目中用過的配置文件(YAML篇)

上圖配置的內容雖然還沒解釋,仔細去看配置,大體都能看明白。其實,這就是 YAML 比 properties 配置文件的優勢所在,層次感分明,配置有序,而且比較簡潔。


縱然配置已經很清晰,還是要稍微帶著看一看配置內容。


dev 是一個對象,對應於 Java 中的 Map,包含 datasources 和 tables 兩個屬性。其本身含義是開發環境配置,當然實際項目中也會有測試、準生產、生產的對應的配置。


datasources 屬性是一個數組,對應於 Java 中的 List,數組元素由 name、default 等 10 個屬性構成。其本身含義是數據源配置,因為涉及到分庫,所以會有好多庫要連接,圖中只列舉兩個數據庫;


tables 屬性也是一個數組,對應於 Java 中的 List,數組元素由 tableName、databaseCount 等 5 個屬性構成。其本身含義是要拆分表的規則配置,圖中只列舉一個項目基本信息表。


按照常規思路,寫好配置文件,接下來就要校驗一下,再稍微格式化一下。

<code>在這兒校驗Yaml文件:http://www.bejson.com/validators/yaml//<code>
細數Java項目中用過的配置文件(YAML篇)

如上圖所示,YAML 文件校驗轉換之後,就真的太清晰啦!


不過,YAML 是很簡單,但是

有些細節,在開發中還是要注意,否則入坑就難跳出(一旦入坑,真的不好跳出來,別問為什麼?一個空格難倒英雄漢,真心體會過)。


Tips:

1. 使用冒號加縮進的方式代表層級關係,使用短橫槓代表數組元素;

2. 注意縮進不允許使用「tab」鍵,只能使用空格鍵(曾經掉這個坑啦,記憶之深刻);

3. 縮進空格個數多少並不重要,只要相同層級的元素左對齊即可;

4. 如果冒號後跟著 value,一定要注意冒號後跟上空格呦!

5. YAML 大小寫很敏感。


有關 YAML 的更多規範,可以參考如下 pdf,本次不過多展開去講。

<code>https://yaml.org/spec/1.2/spec.pdf/<code>


YAML 配置有了,該怎麼去解析呢?


在不同的編程語言中,都有很多三方工具可以解析 YAML 文件,而在 Java 項目可以用 SnakeYaml 進行解析,接下來就寫寫代碼體驗一下 yaml 文件的解析。


首先引入依賴包(想用人家,就別想撇清關係!)

<code><dependency>
<groupid>org.yaml/<groupid>
<artifactid>snakeyaml/<artifactid>
<version>1.18/<version>
/<dependency>/<code>

碼點代碼(從原項目中直接拿來,為了清晰,索性只留解析 YAML 文件部分的代碼,呈現給你)

<code>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> profile;

@SuppressWarnings("unchecked")
public static ArrayList<linkedhashmap>> 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> result = yaml.loadAs(fileReader, Map.class);
profile = (LinkedHashMap<string>) result.get(profileId);
}
}
return (ArrayList<linkedhashmap>>) profile.get(key);
}

public static void main(String[] args) throws IOException {
// 開發環境
String profileId = "dev";

// 數據源集合
ArrayList<linkedhashmap>> datasources = parse(profileId, "datasources");
for (LinkedHashMap<string> 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>> tables = parse(profileId, "tables");
for (LinkedHashMap<string> 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")));
}
}
}/<string>/<linkedhashmap>/<string>/<linkedhashmap>/<linkedhashmap>/<string>/<string>/<linkedhashmap>/<string>/<code>

去掉 main 函數,發現解析代碼沒幾行,跑起來看一看,效果還可以。

細數Java項目中用過的配置文件(YAML篇)

本文中的解析 YAML 文件的代碼,改個類名,就可以直接變成工具類,如果有需要,自行簡單封裝一下就 ok 啦。

其中 SnakeYaml 類庫還有很多 API 可以使用,不一一帶著寫代碼啦,感興趣的自行參考 SnakeYaml 官方文檔,去照貓畫虎敲敲吧。

<code>https://bitbucket.org/asomov/snakeyaml/wiki/Documentation/<code>

另外,細心的你在平時研發時,有沒有發現,有的項目 YAML 文件的後綴是 .yml,有的項目卻是 .yaml,到底哪個是正確的呢?很久很久之前我也糾結過,感興趣可以去 stackoverflow 溜達一番。

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

它山之石相信可以攻玉

有關 YAML 文件在實際項目中的使用,本次就談到這裡,它山之石可以攻玉,希望能對你有所幫助。


分享到:


相關文章: