使用@Value 注入 List 類型的配置屬性需要注意的 BUG
@Value 注入 List 類型的配置屬性
@Value 注解可以方便的幫助我們注入配置屬性值.
那么當注入一個 List 類型時該怎么做呢?
想必大家都會知道,可以使用下面這種寫法:
@Value("#{'${zf.ids}'.split(',')}") private List<Integer> ids;
上面的配置簡單說下就是,先使用 ${zf.ids} 拿到配置文件中 zf.ids 屬性的值,然后使用 #{} 也就是 SPEL 表達式語言進行按,拆分,得到的結(jié)果轉(zhuǎn)為 List<Integer>類型的值.
這樣做沒什么問題,可以說完美解決了 注入復雜類型的配置文件的屬性
那么問題來了
如果 我們想要配置文件沒有 zf.ids屬性的時候注入一個空的 List 該怎么辦呢?
這時候你可能說簡單嘛,給 ${zf.ids}加個默認值就好了: ${zf.ids:}
@Value("#{'${zf.ids:}'.split(',')}") private List<Integer> ids;
如上面所示,我們使用:來給 zf.ids添加一個默認值,為空.
那么這時候,我們的 ids 屬性值的內(nèi)容是什么呢?
是 空的 List<Integer>對象? 還是 ids 的值就是個 null 呢?
我們來實踐一下:看看到底是什么?
打個斷點,調(diào)試走起,可以看到:
竟然不是 空 List,而且有一個值,我們看下 List 中的值到底是什么:
發(fā)現(xiàn)竟然只有一個值為 null 的元素 !
跟蹤源碼查看 @Value("#{'${zf.ids:}'.split(',')}") 的解析過程
其中最關(guān)鍵的一步就是下面整個方法org.springframework.beans.TypeConverterDelegate#convertIfNecessary(java.lang.String, java.lang.Object, java.lang.Object, java.lang.Class, org.springframework.core.convert.TypeDescriptor)
會發(fā)現(xiàn): ${zf.ids:) 被解析為 "" 一個空的字符串;
然后調(diào)用 SpEL 再次解析: #{''.split(',')} 即 返回一個數(shù)組,這個數(shù)組只有一個空的字符串
然后 Spring 會運用一系列的 Converter 進行類型轉(zhuǎn)換,關(guān)鍵就在這一步:
String[] --> List<Integer> 時, 把數(shù)組中的空字符串轉(zhuǎn)為 Integer 類型時,由于不能傳喚,默認就是個 null
整個轉(zhuǎn)過過程就是
[""] --> {""} --> {null}
最后我們就得到了一個只有一個 null 值的 List 集合!
至此,真相大白,在使用 @Value("#{'${zf.ids:}'.split(',')}") 注入 List 屬性的時候尤其需要注意這個問題,搞不好就是個線上 bug ! ! !
@Value注入map、List,yaml格式
使用@Value注入map、List
實體類
@Value("#{'${list}'.split(',')}") private List<String> list; @Value("#{${maps}}") private Map<String,String> maps;
配置文件
list: topic1,topic2,topic3 maps: "{key1: 'value1', key2: 'value2'}"
ps:注意上面的map解析中,一定要用""把map所對應的value包起來,要不然解析會失敗,導致不能轉(zhuǎn)成 Map<String,String>。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java結(jié)構(gòu)型設(shè)計模式之組合模式詳解
組合模式,又叫部分整體模式,它創(chuàng)建了對象組的數(shù)據(jù)結(jié)構(gòu)組合模式使得用戶對單個對象和組合對象的訪問具有一致性。本文將通過示例為大家詳細介紹一下組合模式,需要的可以參考一下2022-09-09SpringBoot實現(xiàn)優(yōu)雅停機的流程步驟
優(yōu)雅停機(Graceful Shutdown) 是指在服務器需要關(guān)閉或重啟時,能夠先處理完當前正在進行的請求,然后再停止服務的操作,本文給大家介紹了SpringBoot實現(xiàn)優(yōu)雅停機的流程步驟,需要的朋友可以參考下2024-03-03IDEA下Servlet可能出現(xiàn)404的一些情況
相信有很多小伙伴遇到報錯都不知道怎么處理,今天特地整理了這篇文章,文中對IDEA下Servlet可能出現(xiàn)404的一些情況作了詳細的介紹,需要的朋友可以參考下2021-06-06Hadoop之NameNode Federation圖文詳解
今天小編就為大家分享一篇關(guān)于Hadoop之NameNode Federation圖文詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01MyBatis-Plus+達夢數(shù)據(jù)庫實現(xiàn)高效數(shù)據(jù)持久化的示例
這篇文章主要介紹了MyBatis-Plus和達夢數(shù)據(jù)庫實現(xiàn)高效數(shù)據(jù)持久化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-08-08Java mutable對象和immutable對象的區(qū)別說明
這篇文章主要介紹了Java mutable對象和immutable對象的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Java8接口中引入default關(guān)鍵字的本質(zhì)原因詳析
Default方法是在java8中引入的關(guān)鍵字,也可稱為Virtual extension methods—虛擬擴展方法,這篇文章主要給大家介紹了關(guān)于Java8接口中引入default關(guān)鍵字的本質(zhì)原因,需要的朋友可以參考下2022-01-01