簡體   English   中英

如何在 kotlin 中使用像 @Autowired 這樣的 spring 注釋?

[英]How to use spring annotations like @Autowired in kotlin?

是否可以在 Kotlin 中執行以下操作?

@Autowired
internal var mongoTemplate: MongoTemplate

@Autowired
internal var solrClient: SolrClient

在 Spring 中進行依賴注入的推薦方法是構造函數注入:

@Component
class YourBean(
    private val mongoTemplate: MongoTemplate, 
    private val solrClient: SolrClient
) {
  // code
}

在 Spring 4.3 構造函數之前,應該使用Autowired顯式注釋:

@Component
class YourBean @Autowired constructor(
    private val mongoTemplate: MongoTemplate, 
    private val solrClient: SolrClient
) {
  // code
}

在極少數情況下,您可能喜歡使用字段注入,並且可以在lateinit的幫助下lateinit

@Component
class YourBean {

    @Autowired
    private lateinit var mongoTemplate: MongoTemplate

    @Autowired
    private lateinit var solrClient: SolrClient
}

構造函數注入在 bean 創建時檢查所有依賴項,所有注入的字段都是val ,另一方面,lateinit 注入的字段只能是var ,並且幾乎沒有運行時開銷。 並且要使用構造函數測試類,您不需要反射。

鏈接:

  1. 關於 lateinit 的文檔
  2. 關於構造函數的文檔
  3. 使用 Kotlin 開發 Spring Boot 應用程序

是的,與 Java 一樣,Kotlin 主要支持 Java 注釋。 一個問題是主構造函數上的注釋需要顯式的 'constructor' 關鍵字:

來自https://kotlinlang.org/docs/reference/annotations.html

如果需要對類的主構造函數進行注解,則需要在構造函數聲明中添加constructor關鍵字,並在其前添加注解:

class Foo @Inject constructor(dependency: MyDependency) {
  // ...
}

您還可以通過構造函數自動裝配依賴項。 記得用@Configuration, @Component, @Service等注釋你的依賴項

import org.springframework.stereotype.Component

@Component
class Foo (private val dependency: MyDependency) {
    //...
}

像那樣

@Component class Girl( @Autowired var outfit: Outfit)

如果您想要屬性注入但不喜歡lateinit var ,這是我使用屬性委托的解決方案:

private lateinit var ctx: ApplicationContext

@Component
private class CtxVarConfigurer : ApplicationContextAware {
    override fun setApplicationContext(context: ApplicationContext) {
        ctx = context
    }
}

inline fun <reified T : Any> autowired(name: String? = null) = Autowired(T::class.java, name)

class Autowired<T : Any>(private val javaType: Class<T>, private val name: String?) {

    private val value by lazy {
        if (name == null) {
            ctx.getBean(javaType)
        } else {
            ctx.getBean(name, javaType)
        }
    }

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value

}

然后你可以by委托語法更好地使用:

@Service
class MyService {

    private val serviceToBeInjected: ServiceA by autowired()

    private val ambiguousBean: AmbiguousService by autowired("qualifier")

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM