天天看點

SpringBoot 的@Value注解真是太強了,誰用誰說爽!一、前言二、數組怎麼樣三、替代方法四、後續

在日常開發中,經常會遇到需要在配置檔案中,存儲 <code>List</code> 或是 <code>Map</code> 這種類型的資料。Spring 原生是支援這種資料類型的,以配置 <code>List</code> 類型為例,對于 <code>.yml</code> 檔案配置如下:

對于 <code>.properties</code> 檔案配置如下所示:

當我們想要在程式中使用時候,想當然的使用 <code>@Value</code> 注解去讀取這個值,就像下面這種寫法一樣:

你會發現程式直接報錯了,報錯資訊如下:

這個問題也是可以解決的,以我們要配置的 key 為 <code>test.list</code> 為例,建立一個 <code>test</code> 的配置類,将 <code>list</code> 作為該配置類的一個屬性:

在程式其他地方使用時候。采用自動注入的方式,去擷取值:

可以看見,這種方式十分的不友善,最大的問題是配置和代碼高耦合了,增加一個配置,還需要對配置類做增減改動。

整理的spring學習筆記分享給大家:176頁Spring學習筆記,完整版

數組?說實話,業務代碼寫多了,這個“古老”的資料結構遠遠沒有 list 用的多,但是它在解決上面這個問題上,出乎異常的好用。

這樣就能夠直接使用了,就是這麼的簡單友善,如果你想要支援不配置 key 程式也能正常運作的話,給它們加上預設值即可:

僅僅多了一個 <code>:</code> 号,冒号後的值表示當 key 不存在時候使用的預設值,使用預設值時數組的 length = 0。總結下使用數組實作的優缺點:

優點 :

不需要寫配置類

使用逗号分割,一行配置,即可完成多個數值的注入,配置檔案更加精簡

缺點*:

業務代碼中數組使用很少,基本需要将其轉換為 List,去做 contains、foreach 等操作。

那麼我們有沒有辦法,在解析 list、map 這些類型時,像數組一樣友善呢?答案是可以的,這就依賴于 <code>EL</code> 表達式。

以使用 <code>.yml</code> 檔案為例,我們隻需要在配置檔案中,跟配置數組一樣去配置:

在調用時,借助 <code>EL</code> 表達式的 <code>split()</code> 函數進行切分即可。

同樣,為它加上預設值,避免不配置這個 key 時候程式報錯:

但是這樣有個問題,當不配置該 key 值,預設值會為空串,它的 length = 1(不同于數組,length = 0),這樣解析出來 list 的元素個數就不是空了。

這個問題比較嚴重,因為它會導緻代碼中的判空邏輯執行錯誤。這個問題也是可以解決的,在 <code>split()</code> 之前判斷下是否為空即可。

如上所示,即為最終的版本,它具有數組方式的全部優點,且更容易在業務代碼中去應用。

解析 Set 和解析 List 本質上是相同的,唯一的差別是 Set 會做去重操作。

解析 Map 的寫法如下所示,value 為該 map 的 JSON 格式,注意這裡使用的引号:整個 JSON 串使用引号包裹,value 值使用引号包裹。

在程式中,利用 EL 表達式注入:

注意,使用這種方式,必須得在配置檔案中配置該 key 及其 value。我在網上找了許多資料,都沒找到利用 EL 表達式支援不配置 key/value 的寫法。如果你真的很需要這個功能,就得自己寫解析方法了,這裡以使用 fastjson 進行解析為例:

(1) 自定義解析方法

(2) 在程式中指定解析方法

以上就是本文的全部内容,利用 EL 表達式、甚至是自己的解析方法,可以讓我們更加友善的配置和使用 Collection 類型的配置檔案。特别注意的是 <code>@Value</code> 注解不能和 <code>@AllArgsConstructor</code> 注解同時使用,否則會報錯

這種做法唯一不優雅的地方就是,這樣寫出來的 <code>@Value</code> 的内容都很長,既不美觀,也不容易閱讀。