在Java 的世界裏,配置的事情都交給了 Properties,要追溯起來這個模塊還是從古老的JDK1.0 就開始了的。
"天哪,這可是20年前的東西了,我居然還在用 Properties.."
然而,本文的主角並不是Properties,而是Yaml。這是新時代裏微服務架構上的寵兒,和 Properties 相比起來,Yaml 顯得有些弄潮兒。
以往的大多數項目裏,我們都可以發現 Properties配置文件的蹤跡,這包括用作業務屬性配置的、機機接口交互的、國際化的等等用途。
而少量的一些情況下,也存在一些"混合式"的做法,比如:
- 使用 Xml 來表示一些模板
- 使用一個 Json 格式化的字符串
- 裸奔的文本格式,應用自解析
...
混雜的配置方式往往出現在一些充滿"壞味道"的項目裏頭,因爲代碼陳舊、斯人已矣 等原因,很難形成統一的方式。
然而,除開 Properties 屬性文件這種簡單的配置方式之外,採用其他的方法不外乎都是爲了適應配置複雜、多元化的訴求。
那麼,Yaml 就是應對這種場景而產生的,在 SpringBoot 的官方文檔中,有不少篇幅是 使用了 Yaml 語法的配置格式。
下面介紹一下 Yaml 以及它是如何使用的。
一、什麼是 Yaml
來自百科的定義:
"Yaml 是一個可讀性高,易用的數據序列化格式,由 Clark Evans 在2001年首次發表。"
可見 Yaml 並不是一個很新的東西,只是在以前接觸的人不多罷了。此外,Yaml也被各種編程語言及框架所支持, 通用性很高。
在Java體系中,一般的微服務框架都支持甚至優先推薦使用 Yaml 作爲首選的配置語言。
而 Yaml 本身具有什麼特點? 看看下面的一個實例:
environments:
dev:
url: https://dev.example.com
name: Developer Setup
prod:
url: https://another.example.com
name: My Cool App
這段語法等價的 Properties 爲:
environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App
可見, yaml 相對來說更加的結構化,更適合用來表達一個對象。
它在語法上有這樣的特點:
- 大小寫敏感
- 使用空格縮進表示層級關係,摒棄使用Tab鍵,這主要是考慮到不同平臺上文本展現時需要對齊
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
- 使用 # 開頭作爲註釋行
- 使用 連接符(-)開頭來描述數組元素
對比 Properties
Properties 可以很好的實現 Key-Value 的配置,包括作爲一些國際化內容的配置方式。
但 Properties 很難表現多層級的嵌套關係,此時如果用 Yaml 可以較好的彌補該短板。
對比 Json
Yaml 與 Json本身沒有太多的優劣之分,兩者都是結構化的表達式語言,但是Json的設計重點在於簡單易用、方便傳輸的特性;
而 Yaml 則側重於可讀性(更加在乎外觀),幾乎可以把 Yaml 看做是 Json 的一個"超集",即可讀性更高(更漂亮) 的結構化格式。
此外,Json更加便於生成和解析,適合在各種跨語言、分佈式的環境中傳輸和交互;與此同時, Yaml 則一般只是用作的配置較多。
關於 Yaml 的定義可以訪問下面的地址:
http://www.yaml.org/spec/1.2/spec.html
二、Yaml 的語法
Yaml 是非常簡單的, 它所定義的元素只有三個:
- 對象:就是鍵值對的集合,對應於Java 中的 HashMap
- 數組:指一組按序排列的值,對應於Java 中的 List
- 單值:單個的、不可再分的值,比如 3,"Jackson"
對象如何表示
一個對象的屬性、嵌套關係通過空格縮進對齊來表示,如下:
article:
title: 一個人的自白書
author:
name: 陳玲
gender: female
數組如何表示
數組的元素通過連接符(-)來表示,如下:
article:
title: 一個人的自白書
tags:
- 傳記
- 社會
- 人物
構成對象、數組內容的基本單元是單值,Yaml支持的單個值的類型有七種,如下:
類型 | 範例 |
---|---|
字符串 | Bob |
布爾值 | true |
整數 | 199 |
浮點數 | 19.91 |
Null | ~ |
時間 | 2001-12-14T22:14:09.10+08:00 |
日期 | 2019-01-09 |
其中,日期、時間使用的是 ISO 8601 國際標準格式,關於它的定義可以參考:
https://www.w3.org/TR/NOTE-datetime
一般情況下單個值會在一行內結束。但如果遇到多行的字符串,可以使用一些特殊字符表示,
比如:
text: |
Hello
World
對應的結果爲:
{ text: 'Hello\nWorld\n' }
可以用+表示保留字符串末尾的換行,-表示刪除字符串末尾的換行:
text1: |+
Hello
text2: |-
Hello
對應的結果爲:
{ text1: 'Hello\n\n\n', text2: 'Hello' }