具有 Spring DI 的 Kotlin:lateinit 属性 尚未初始化
Kotlin with Spring DI: lateinit property has not been initialized
我无法在 Kotlin 中使用基于 Spring 的 setter 依赖注入,因为它总是以错误消息 "lateinit property api has not been initialized" 终止。我可以将问题简化为以下场景:有一个接口
interface IApi {
fun retrieveContent(): String
}
由
实施
class Api : IApi {
override fun retrieveContent() = "Some Content"
}
我想在另一个 class 应该进行依赖注入的地方使用该实现:
@Component
class SomeController {
@Autowired lateinit var api: IApi
fun printReceivedContent() {
print(api.retrieveContent())
}
}
但是,应用程序终止并显示上述错误消息。我的 Spring 配置如下所示:
@Configuration
open class DIConfig {
@Bean
open fun getApiInstance(): IApi = Api()
}
在主函数中,我加载了应用程序上下文并调用了方法:
fun main(args: Array<String>) {
val context = AnnotationConfigApplicationContext()
context.register(DIConfig::class.java)
context.refresh()
val controller = SomeController()
controller.printReceivedContent()
}
这里有什么问题?
通常将@Autowired
添加到属性的setter。因此,不要将它用于 属性,您应该明确注释 setter:
@set:Autowired lateinit var api: IApi
Spring 如果您只是像那样自己调用构造函数,则不涉及。与 Java、
相同
val controller = context.getBean(SomeController::class.java)
Spring Framework 5.0 增加了Kotlin extensions,所以你也可以这样写
val controller = context.getBean<SomeController>()
val controller: SomeController = context.getBean()
您的 api 目前不是由 spring 管理的 bean,请尝试使用 @Service 或 @Component
对其进行注释
我无法在 Kotlin 中使用基于 Spring 的 setter 依赖注入,因为它总是以错误消息 "lateinit property api has not been initialized" 终止。我可以将问题简化为以下场景:有一个接口
interface IApi {
fun retrieveContent(): String
}
由
实施class Api : IApi {
override fun retrieveContent() = "Some Content"
}
我想在另一个 class 应该进行依赖注入的地方使用该实现:
@Component
class SomeController {
@Autowired lateinit var api: IApi
fun printReceivedContent() {
print(api.retrieveContent())
}
}
但是,应用程序终止并显示上述错误消息。我的 Spring 配置如下所示:
@Configuration
open class DIConfig {
@Bean
open fun getApiInstance(): IApi = Api()
}
在主函数中,我加载了应用程序上下文并调用了方法:
fun main(args: Array<String>) {
val context = AnnotationConfigApplicationContext()
context.register(DIConfig::class.java)
context.refresh()
val controller = SomeController()
controller.printReceivedContent()
}
这里有什么问题?
通常将@Autowired
添加到属性的setter。因此,不要将它用于 属性,您应该明确注释 setter:
@set:Autowired lateinit var api: IApi
Spring 如果您只是像那样自己调用构造函数,则不涉及。与 Java、
相同val controller = context.getBean(SomeController::class.java)
Spring Framework 5.0 增加了Kotlin extensions,所以你也可以这样写
val controller = context.getBean<SomeController>()
val controller: SomeController = context.getBean()
您的 api 目前不是由 spring 管理的 bean,请尝试使用 @Service 或 @Component
对其进行注释