springboot属性注入异常之谜

在上一篇文件中介绍了springboot加载配置文件的方式,即从"./config;./;classpath:/config;classpath:/“等4个地方加载配置文件,配置文件的属性按顺序保存在environment对象的propertysource对象中,当我们读取配置信息时即从propertysource列表中依次查找直到找到为止。
举个例子,我们的应用在”./"和“classpath:/”中分别有一个application-dev.yml的配置文件,在“./”路径下的配置文件有属性“aa.bb= 1”,在"classpath:./“路径下的配置文件有属性"aa.bb=2”。那么当我们调用environment.getProperty(“aa.bb”)时,由于系统会先在“./”路径下的配置文件的配置文件中找到该值,因此系统将不在继续往下查到,因此aa.bb的值为1。
这样看的话好像没有什么问题,但是当aa.bb不在是当个string类型的值而是一个map对象的时候,可就不是那么回事了。
举个例子,“classpath:/”路径下的application-dev.yml配置文件中存在如下配置:
aa.bb={a=1;b=1;c=1},在“./”路径下的配置文件中存在如下配置:aa.bb={},那么系统中“aa.bb”是什么呢,通过定义一个bean可以进行测试:

@Bean
    @ConfigurationProperties(prefix = "aa")
    public aaObj aaObj(){
        return new aaObj();
    }

如上aaObj只有一个属性:Map bb;
通过测试我们可以发现aaObj.bb = {a=1;b=1;c=1}
这个问题当时困扰了我一两个小时,后来因为有其他工作就直接把classpath下的配置文件删了才算绕过去,今天正好有时间了正好来研究下这个问题。
一开始我打算在程序中通过Map map = environment.getProperty(“aa.bb”,Map.class)来测试,结果发现获取的值为null,经过调试发现,配置文件中的aa.bb={a=1;b=1;c=1}被系统拆解成了“aa.bb.a =1;aa.bb.b=1;aa.bb.c=1”共三个配置项environment.getProperty需要完全equals才算匹配上。那么@ConfigurationProperties(prefix = “aa”)
注解又是如何完成map类型的属性注入的呢,具体的代码写在MapBinder.bindEntries里:

public void bindEntries(ConfigurationPropertySource source, Map<Object, Object> map) {
			if (source instanceof IterableConfigurationPropertySource) {
				for (ConfigurationPropertyName name : (IterableConfigurationPropertySource) source) {
					Bindable<?> valueBindable = getValueBindable(name);
					ConfigurationPropertyName entryName = getEntryName(source, name);
					Object key = getContext().getConverter().convert(getKeyName(entryName), this.keyType);
					map.computeIfAbsent(key, (k) -> this.elementBinder.bind(entryName, valueBindable));
				}
			}
		}

打断点调试source对象,可以看到他就是environment的sourceProperty,但是不同的是这个source多了一个filter,filter属性为“aa.bb”,然后再ConfigurationPropertyName name : (IterableConfigurationPropertySource) source 中遍历出来的属性就全部是aa.bb有关的。
通过上面的分析我们可以知道,当我们在配置文件中注入map类型的属性时,需要注意springboot对这类配置的处理。总的来说,我觉得还是删除那些不打算使用的配置文件比较靠谱呀,不然的话真的会变成一场灾难。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值