Можно ли использовать во вложенном классе свойств конфигурации java Spring значение из родительского элемента для инициализации дочернего элемента?
У меня есть веб-служба SpringBoot 2, Kotlin/Java, которая использует @ConfigurationProperties для загрузки вложенного набора классов / свойств для использования во время выполнения. Все работает правильно, за исключением одного: я не могу понять, как передать значение (код) из родительского класса (TenantProperties) в его вложенный дочерний класс (DatabaseProperties). В следующем фрагменте, извлеченном из другого родителя с соответствующими аннотациями, я пытаюсь передать код в TenantProperties в DatabaseProperties при его создании. Что бы я ни пробовал, родитель всегда передает потомку null. Буду признателен за любые предложения.
class TenantProperties(
var code: String? = null,
var id: String? = null,
var name: String? = null,
var db: DatabaseProperties = DatabaseProperties(code),
var blob: BlobProperties = BlobProperties(code)
) {
class DatabaseProperties(
var code: String?,
var uriTemplate: String? = null,
var username: String? = null,
var password: String? = null
) {
fun connectionString() = "$uriTemplate".format(username, password, code)
}
}
1 ответ
В вашем примере вы инициализируете классы вместе с родительским объектом. Параметры конфигурации пружины вводятся позже. Таким образом, ваши вложенные классы всегда инициализируются значением по умолчанию, поэтому настроенныйcode
никогда не будет передан.
Чтобы заставить ваш код работать, я предлагаю сделать классы внутренними классами (чтобы позволить им получить доступ к внешнему) и лениво инициализировать свойство post-built:
@Configuration
@ConfigurationProperties(value = "my")
class TenantProperties {
lateinit var code: String
lateinit var id: String
lateinit var name: String
val db = DatabaseProperties()
inner class DatabaseProperties {
lateinit var uriTemplate: String
lateinit var username: String
lateinit var password: String
val connectionString by lazy { "$uriTemplate".format(username, password, code) }
}
}
Делаем все переменные lateinit
вы получаете некоторую безопасность типов. Чтобы сделать его еще более надежным, вы можете добавить несколько валидаторов:
@Configuration
@ConfigurationProperties(value = "my", ignoreUnknownFields = false, ignoreInvalidFields = false)
class TenantProperties {
@NotNull lateinit var code: String
@NotNull lateinit var id: String
@NotNull lateinit var name: String
val db = DatabaseProperties()
inner class DatabaseProperties {
@NotNull lateinit var uriTemplate: String
@NotNull lateinit var username: String
@NotNull lateinit var password: String
val connectionString by lazy { "$uriTemplate".format(username, password, code) }
}
}
теперь твой application.properties
может выглядеть так:
my.code=aCode
my.id=anId
my.name=aName
my.db.uri-template=http://localhost
my.db.username=admin
my.db.password=pw