Springboot 与地图的放松绑定正在复制属性



我有一个看起来像这样的application.yml:

root:
mapkey:
name-with-dashes:
vara: some value 1
varb: 1
different-name-with-dashes:
vara: some value 2
varb: 2

我正在使用@ConfigurationProperties注释来注入与此结构匹配的配置 POJO。它基本上看起来像这样(为了可读性而删除了构造函数等,但只要知道它有效(:

@Configuration
@ConfigurationProperties("root")
public class ParentConfig {
private Map<String, ChildConfig> mapkey;
}
public class ChildConfig {
private String vara;
private Integer varb;
}

在本地测试时,我没有问题,并且注入工作正常。

但是,在尝试使用系统变量部署和覆盖这些字段时,我遇到了问题。在 Springboot 文档中,它说应该通过将句点转换为下划线、删除破折号并转换为大写来创建系统属性。就我而言,我最终会得到这样的变量:

ROOT_MAPKEY_NAMEWITHDASHES_VARA: deployment value 1
ROOT_MAPKEY_NAMEWITHDASHES_VARB: 6
ROOT_MAPKEY_DIFFERENTNAMEWITHDASHES_VARA: deployment value 2
ROOT_MAPKEY_DIFFERENTNAMEWITHDASHES_VARB: 12

但是,当我使用这些变量运行应用程序并检查ParentConfig对象时,映射如下所示:

{
mapkey: {
name-with-dashes: {
vara: deployment value 1
varb: 6
}, 
namewithdashes: {
vara: deployment value 1
varb: 6
}, 
different-name-with-dashes: {
vara: deployment value 2
varb: 12
}, 
differentnamewithdashes: {
vara: deployment value 2
varb: 12
}
}
}

它复制带有和不带破折号的属性,我不知道为什么。不仅如此,所有值都具有部署值,而不是 application.yml 值。非常令人困惑。

最近,我在"宽松绑定"方面遇到了类似的问题。我的问题是我的内部配置没有被外部配置覆盖,其中内部配置完全匹配,而外部配置不是。所以这里有相似之处,但与您的不完全一样。但是,当我将外部配置更改为完全匹配时,它会覆盖。

我还没有找到任何关于此的文档,但我相当确定这是一个优先问题以及绑定实际上有多"放松"。就我而言,内部精确匹配优先而丢弃"宽松"的外部匹配(旧错别字(是完全有道理的。

回答你的问题,因为你的对象是一个地图,其中对不是以严格的键开头。这使得覆盖变得更加模糊(如果不是不可能的话(。我的想法是,除非完全匹配,否则它无法区分新键和要覆盖的键。因此,将新系统 env-var 作为新键插入是有意义的。

现在你可能会问在这种情况下如何精确。好吧,你不能,除非你改变你的内部配置以遵循系统属性命名规则。或者,您可以拥有具有确切命名的外部配置文件。

总的来说,我认为"宽松绑定"更像是一种后备选择。它不应该是你的首选。尽可能使用精确命名。我想说的是,当旧项目升级到新版本并且开发人员不必通过大量配置文件来更改名称时,此功能可能更有帮助。

最新更新