Использование свойств lateinit в конструкторе в kotlin - PullRequest
1 голос
/ 12 марта 2019

Как я могу использовать свойства lateinit в конструкторе моего класса:

У меня есть пружинный компонент, который я использую для настройки и доступа к сторонней библиотеке, например:

@Service
class LibProxy {

    @Value("\${lib.someProperty}")
    private lateinit var someProperty: String

    final var lib: Lib

    init {
        lib = Lib(someProperty)
    }
}

Это дает

kotlin.UninitializedPropertyAccessException: lateinit property someProperty has not been initialized

Как это должно быть сделано?

Я бы хотел избежать таких конструкций:

@Service
class LibProxy {

    @Value("\${lib.someProperty}")
    private lateinit var someProperty: String

    private var lib: Lib? = null

    getLib(): Lib {
        if (lib == null) {
            lib = Lib(someProperty)
        }
        return lib ?: Lib(someProperty)
    }
}

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Две возможности здесь:

Самый простой способ - заменить блок init методом @PostConstruct. Spring вызовет это один раз, после того, как объект будет построен (и, следовательно, все значения автопроводки установлены). Например:

@PostConstruct
private fun initialise() {
    lib = Lib(someProperty)
}

Другой способ организовать передачу свойства autowired в конструкторе, а не в качестве свойства (согласно другим ответам).

Один подход, который работает хорошо, особенно если у вас есть несколько свойств конфигурации, - это иметь центральный класс, хранящий их:

@ConfigurationProperties("lib")
class ConfigProperties {
    var someProperty = "defaultValue"
    // …and other properties…
}

Это будет устанавливать someProperty из значения "lib.someProperty" в файле конфигурации (или оставить как "defaultValue", если его нет).

Затем вы можете автоматически связать его экземпляр в конструкторе, например ::

class SomeService @Autowired constructor(
    private val configProperties: ConfigProperties) {

    init {
        lib = Lib(configProperties.someProperty)
    }
}

(Централизация свойств также может упростить поиск доступных свойств.)

1 голос
/ 12 марта 2019

Согласно комментарию JEY .Вот как это должно быть сделано:

@Service
class LibProxy(@Value("\${lib.someProperty}") private val someProperty: String) {

    final var lib: Lib

    init {
        lib = Lib(someProperty)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...