MicroProfile Config・對啊~就是設定

MicroProfile Config(後續簡稱 MPConfig)顧名思義,就是要來解決「設定」的問題。
可能很多人會有疑惑,設定是有什麼什麼好聊的,成熟的工具比比皆是,光標準的就有 Java SE 的 Properties、Java Web 的 web.xml,為了使用 MicroProfile 還要再多學一個,當軟體工程師是要有多艱難 Orz...

好吧,在我完全讀完 MPConfig 後,我認為,正是因為有這些艱難,所以有了這個技術!
不談別的技術,就談談我自己的困擾:

  • 取得設定的數值頗麻煩,或是寫起來很彆扭,沒有乾脆俐落的爽快
  • 取得設定的數值怎麼都是字串,還要自己轉
  • 要取得的設定沒辦法保證一定存在,還要另外處理
  • 設定分散在好多地方,每個地方要存取的方式都不一樣,真是很糾結啊...

若心有戚戚焉,真的可以考慮採用喔喔喔喔喔!!!!!
先總結一下 MPConfig 的特性:

  • 乾脆俐落的爽快寫法
  • 不用擔心漏了設定
  • 自動轉換資料型態
  • 可以擴充數值的資料來源
    • 本文不討論怎麼擴充,有興趣可以看規格書實作喔

以下將針對這些方便的特性進行簡要的說明及示範,強烈建議 閱讀規格書,寫得真的很清楚,特性、限制等等都有完整說明。


在開始之前

開始之前,有幾個重點要先說明:

  1. 以下分享的都是用 @Inject 的方式,所以在練習的時候,請確保 CDI 容器能管理要 inject object 的那個 class
  • CDI 是 MicroProfile 從 Java EE(現在的 Jakarta EE)中借來的框架,主要用途是用來撰寫應用邏輯,並由 CDI Container 管理 object 的生命週期
  1. 此框架有 Default ConfigSources,且有權重概念在框架中
  • 簡單說 => 有預設的設定檔資料來源,且優先順序不同
  1. 本文將採用 microprofile-config.properties 的設定方式
  • 設定檔的位置請放置在 ProjectRoot -> src -> main -> resources -> META-INF 資料夾之中

乾脆俐落的爽快寫法

你想象的簡單俐落是怎麼樣呢?
MPConfig 的制定者們明確的告訴大家,他們期望的方式是使用 annotation 進行 inject。

# microprofile-config.properties
author=Arren Ping
// in CDI managed bean
@Inject
@ConfigProperty(name = "author")
private String author;

不需要特殊的初始化方式
不需要使用指定的 method
只要 @Inject @ConfigProproty 然後 JUST WORK!!
真的好幸福啊,這麼寫程式真的蠻爽的~(愉悅

另外,針對 複數數值 也有提供下述方法進行設定:

# microprofile-config.properties
skill=Java,Java EE,Jakarta EE
// in CDI managed bean
@Inject
@ConfigProperty(name = "skill")
private String[] skill;

要特別提醒使用複數數值的時候,

  1. 是以 , 進行分隔,前後都不需要留空格;
  2. 如果要保留 , 請使用 \\, 來標示;
  3. 除了 String[] 以外,還支援 List<String>Set<String> 方便使用者直接使用

是不是很簡單呢?

不用擔心漏了設定

開發系統時,有時候會需要插些旗子,透過設定來啟動某些模式,這種時候可以這樣處理:

// in CDI managed bean
@Inject
@ConfigProperty(name = "mode", defaultValue = "DEV")
private String mode;

是的,設定檔中沒有加入這個設定值,所以必須要加入 defaultValue
但若是沒有加入 defaultValue 會發生什麼事情呢?答案是「部署期間會拋出異常」,藉由拋出異常來警告開發人員,有地方怪怪的喔~

如果,既不想拋出異常,也不想要設定 defaultValue,那怎麼辦?這樣要求會不會太機車?
有喔~也有方案!

// in CDI managed bean
@Inject
@ConfigProperty(name = "mode")
private Optional<String> mode;

用個 Optional 來接就可以了!不得不說,真的好貼心啊~~~

自動轉換資料型態

然而,貼心不僅止於此,資料型態的轉換真的太過癮了!

# microprofile-config.properties
level=0
// in CDI managed bean
@Inject
@ConfigProperty(name = "level")
private int level;

連指定類型都不用,直接 自 動 轉 換!!!(撒花

什麼?你說應該是只支援內建幾種轉換方法吧!?
不不不!就算是自己設計的 class 也可以自動轉換唷~

# microprofile-config.properties
level=0
// Custom Level Class
public class Level {

    private int level;
    
    public int getLevel() {
        return level;
    }
    
    public void setLevel(int level) {
        this.level = level;
    }
    
    public static Level of(String level) {
        var result = new Level();
        result.setLevel(Integer.parseInt(level));
        return result;
    }
}
// in CDI managed bean
@Inject
@ConfigProperty(name = "level")
private Level level;

鐺鐺!只要添加一個 public static Level of(String level) 方法就可以了!
這是自動轉換原則的第一條,想知道更多原則請參考 Automatic Converters

提供這樣的彈性,也就代表了幾乎想怎麼 @Inject 就怎麼 @Inject
開心的用~專心在應用邏輯就好啦!!!


最後做個簡單的結語,

後續在相容 MicroProfile 環境開發時,若需要設定環境數值我會直接採用!

by Arren Ping