使用@Value|使用@Value 注入 List 类型的配置属性需要注意的 BUG
@Value 注入 List 类型的配置属性
@Value 注解可以方便的帮助我们注入配置属性值.
那么当注入一个 List 类型时该怎么做呢?
想必大家都会知道,可以使用下面这种写法:
@Value("#{'${zf.ids}'.split(',')}") private Listids;
上面的配置简单说下就是,先使用 ${zf.ids} 拿到配置文件中 zf.ids 属性的值,然后使用 #{} 也就是 SPEL 表达式语言进行按,拆分,得到的结果转为 List
这样做没什么问题,可以说完美解决了 注入复杂类型的配置文件的属性
那么问题来了
如果 我们想要配置文件没有 zf.ids属性的时候注入一个空的 List 该怎么办呢?
这时候你可能说简单嘛,给 ${zf.ids}加个默认值就好了: ${zf.ids:}
@Value("#{'${zf.ids:}'.split(',')}") private Listids;
如上面所示,我们使用:来给 zf.ids添加一个默认值,为空.
那么这时候,我们的 ids 属性值的内容是什么呢?
是 空的 List
我们来实践一下:看看到底是什么?
打个断点,调试走起,可以看到:
文章图片
竟然不是 空 List,而且有一个值,我们看下 List 中的值到底是什么:
文章图片
发现竟然只有一个值为 null 的元素 !
跟踪源码查看 @Value("#{'${zf.ids:}'.split(',')}") 的解析过程
其中最关键的一步就是下面整个方法org.springframework.beans.TypeConverterDelegate#convertIfNecessary(java.lang.String, java.lang.Object, java.lang.Object, java.lang.Class, org.springframework.core.convert.TypeDescriptor)
文章图片
会发现: ${zf.ids:) 被解析为 "" 一个空的字符串;
然后调用 SpEL 再次解析: #{''.split(',')} 即 返回一个数组,这个数组只有一个空的字符串
文章图片
然后 Spring 会运用一系列的 Converter 进行类型转换,关键就在这一步:
String[] --> List
整个转过过程就是
[""] --> {""} --> {null}最后我们就得到了一个只有一个 null 值的 List 集合!
至此,真相大白,在使用 @Value("#{'${zf.ids:}'.split(',')}") 注入 List 属性的时候尤其需要注意这个问题,搞不好就是个线上 bug ! ! !
@Value注入map、List,yaml格式 使用@Value注入map、List
实体类
@Value("#{'${list}'.split(',')}")private List list; @Value("#{${maps}}")private Map maps;
配置文件
list: topic1,topic2,topic3maps: "{key1: 'value1', key2: 'value2'}"
ps:注意上面的map解析中,一定要用""把map所对应的value包起来,要不然解析会失败,导致不能转成 Map。
【使用@Value|使用@Value 注入 List 类型的配置属性需要注意的 BUG】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- 带有Hilt的Android上的依赖注入
- 解决SpringBoot引用别的模块无法注入的问题
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件