具有不可变属性的@ConstructorBinding 不适用于 Spring Boot Kotlin 中的 @Value @ConfigurationProperties

Posted

技术标签:

【中文标题】具有不可变属性的@ConstructorBinding 不适用于 Spring Boot Kotlin 中的 @Value @ConfigurationProperties【英文标题】:@ConstructorBinding with immutable properties don't work with @Value in Spring Boot Kotlin @ConfigurationProperties 【发布时间】:2021-06-03 14:33:34 【问题描述】:

Spring Boot 支持 @ConfigurationProperties 的 Kotlin data 类。

@ConstructorBinding
@ConfigurationProperties(prefix = "prefix")
data class AppProperties (
    val something: String
)

但是val@ConstructorBinding 有一些限制。您不能将一个变量别名为另一个变量。假设您在 Kubernetes 中运行并想要捕获主机名,该主机名由 env var HOSTNAME 给出。最简单的方法是将@Value("\$HOSTNAME:)" 应用于属性,但它仅适用于可变属性并且没有构造函数绑定。

Spring Boot GitHub 问题跟踪器说:

停止!!请询问有关如何使用某物的问题,或了解为什么某物不是 使用 spring-boot 标记在 Stack Overflow 上按预期工作。

那么,这是一个已知的限制,还是我应该为他们创建一张票来修复它?

编辑: 已开通https://github.com/spring-projects/spring-boot/issues/25552

【问题讨论】:

我不认为这是需要解决的问题。不要误会我的意思,但我相信你在滥用它。您可以依靠它的强大功能,而不是为 Properties 的类创建“别名”。例如,您可以将所需的属性设置为您的application.properties,只需执行类似prefix.something=$HOSTNAME 的操作 @MarcosBarbero "我相信你在滥用它" 滥用是一个强烈的词,表示你有不同的意见。我知道我可以在application.properties 中做些什么,但没有理由不能在代码中做到这一点,特别是因为你可以在 Java 中很好地做到这一点。你有权发表你的意见,但除非你能证明这是一种滥用,否则我建议避免这样说。 另外,如果是图书馆,没有application.properties,所以再试一次。 对不起,英语不是我的母语,我无意在任何时候不尊重你。我仍然坚持我刚才所说的话。换句话说,您不应该在 @ConfigurationProperties 类中混合 @Value 好的,如果它是一个库,正如你所说,并且基于所描述的,它将被 spring-boot 应用程序使用。你有几个选择来实现你想要的。这个链接可能对你有帮助***.com/questions/28892948/…,做你想做的不是其中之一。 【参考方案1】:

@ConfigurationProperties 是an alternative to @Value,两者并非设计为一起使用。它可以与 JavaBean 样式的绑定一起使用,但这只是偶然而不是设计使然,因此不应依赖它。

建议您通过其他方式这样做,而不是使用@Value 来为通过@ConfigurationProperties 绑定的内容设置别名。例如,您可以使用 this answer 中建议的方法之一,Marcos Barbero 在您的问题的 cmets 中链接到该方法。或者,您可以从this example in the documentation 中汲取灵感,并在application.properties 中使用占位符:

prefix.something=$hostname

另一种选择是通过META-INF/spring.factories 注册EnvironmentPostProcessor 的实现,它将PropertySource 添加到环境中以设置所需的别名。目前,如果您想在可重用的库中做某事,这可能是最好的方法。有an open issue 删除当前涉及的一些仪式。

【讨论】:

以上是关于具有不可变属性的@ConstructorBinding 不适用于 Spring Boot Kotlin 中的 @Value @ConfigurationProperties的主要内容,如果未能解决你的问题,请参考以下文章

将具有多个属性的可变数组保存到 plist

不可变类

具有可变数量属性的枚举成员的 Python 元类

无法覆盖“UIRefreshControl”类型的可变属性“refreshControl”?具有协变类型“UIRefreshControl”

如何在视图之间创建具有可变间距的 UIStackView?

选择具有可变数据属性的元素,但有些带有破折号