[英]Spring boot annotation @ConfigurationProperties doesn't work correctly classes with nested collection in Kotlin
有带有@ConfigurationProperties 和@ConstructorBinding 的数据class。 此 class 包含集合字段。 有几个属性源(application.yml、application-dev1.yml)初始化集合的第一个元素。 此元素的绑定无法正常工作。 初始化值仅从一个属性源中提取。 预期行为与某些嵌套 class 类型的字段相同:合并来自所有属性源的值。
Kotlin 属性 class
@ConfigurationProperties("tpp.test.root")
@ConstructorBinding
data class RootPropperties(
var rootField1: String = "",
var rootField2: String = "",
var nested: NestedProperties = NestedProperties(),
var nestedList: List<NestedListProperties> = listOf()
) {
data class NestedProperties(
var nestedField1: String = "",
var nestedField2: String = ""
)
@ConstructorBinding
data class NestedListProperties(
var nestedListField1: String = "",
var nestedListField2: String = ""
)
}
应用程序.yml
tpp:
test:
root:
root-field1: default
nested:
nested-field1: default
nested-list:
- nested-list-field1: default
应用程序-dev1.yml
tpp:
test:
root:
root-field2: dev1
nested:
nested-field2: dev1
nested-list:
- nested-list-field2: dev1
测试
@ActiveProfiles("dev1")
@SpringBootTest
internal class ConfigurationPropertiesTest {
@Autowired
lateinit var environment: Environment
@Autowired
lateinit var rootPropperties: RootPropperties
@Test
fun `configuration properties binding`() {
Assertions.assertEquals("default", rootPropperties.rootField1)
Assertions.assertEquals("dev1", rootPropperties.rootField2)
Assertions.assertEquals("default", rootPropperties.nested.nestedField1)
Assertions.assertEquals("dev1", rootPropperties.nested.nestedField2)
Assertions.assertTrue(rootPropperties.nestedList.isNotEmpty())
//org.opentest4j.AssertionFailedError:
//Expected :default
//Actual :
Assertions.assertEquals("default", rootPropperties.nestedList[0].nestedListField1)
Assertions.assertEquals("dev1", rootPropperties.nestedList[0].nestedListField2)
}
@Test
fun `environment binding`() {
Assertions.assertEquals("default", environment.getProperty("tpp.test.root.root-field1"))
Assertions.assertEquals("dev1", environment.getProperty("tpp.test.root.root-field2"))
Assertions.assertEquals("default", environment.getProperty("tpp.test.root.nested.nested-field1"))
Assertions.assertEquals("dev1", environment.getProperty("tpp.test.root.nested.nested-field2"))
Assertions.assertEquals("default", environment.getProperty("tpp.test.root.nested-list[0].nested-list-field1"))
Assertions.assertEquals("dev1", environment.getProperty("tpp.test.root.nested-list[0].nested-list-field2"))
}
}
使用 RootProperties 的测试在assertEquals("default", rootPropperties.nestedList[0].nestedListField1)上失败,因为rootPropperties.nestedList[0].nestedListField1的值为空。 所有其他断言测试都成功通过。 绑定仅用于收集无法正常工作。
同时环境测试成功通过。 并且Environment.getProperty("tpp.test.root.nested-list[0].nested-list-field1")解析更正值: "default" 。
Spring 启动版本:2.6.4
可能的解决方法是将 List 切换到 Map。
属性 class
@ConfigurationProperties("tpp.test.root-map")
@ConstructorBinding
data class RootMapPropperties(
var rootField1: String = "",
var rootField2: String = "",
var nested: NestedProperties = NestedProperties(),
var nestedMap: Map<String, NestedMapProperties> = mapOf()
) {
data class NestedProperties(
var nestedField1: String = "",
var nestedField2: String = ""
)
data class NestedMapProperties(
var nestedMapField1: String = "",
var nestedMapField2: String = ""
)
}
应用程序.yml
tpp:
test:
root-map:
root-field1: default
nested:
nested-field1: default
nested-map:
1:
nested-map-field1: default
应用程序-dev1.yml
tpp:
root-map:
root-field2: dev1
nested:
nested-field2: dev1
nested-map:
1:
nested-map-field2: dev1
测试
@ActiveProfiles("dev1")
@SpringBootTest
internal class ConfigurationPropertiesMapTest {
@Autowired
lateinit var environment: Environment
@Autowired
lateinit var rootPropperties: RootMapPropperties
@Test
fun `configuration properties binding`() {
Assertions.assertEquals("default", rootPropperties.rootField1)
Assertions.assertEquals("dev1", rootPropperties.rootField2)
Assertions.assertEquals("default", rootPropperties.nested.nestedField1)
Assertions.assertEquals("dev1", rootPropperties.nested.nestedField2)
Assertions.assertTrue(rootPropperties.nestedMap.isNotEmpty())
Assertions.assertEquals("default", rootPropperties.nestedMap["1"]!!.nestedMapField1)
Assertions.assertEquals("dev1", rootPropperties.nestedMap["1"]!!.nestedMapField2)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.