[英]How to use spring annotations like @Autowired in kotlin?
Is it possible to do something like following in Kotlin?是否可以在 Kotlin 中执行以下操作?
@Autowired
internal var mongoTemplate: MongoTemplate
@Autowired
internal var solrClient: SolrClient
Recommended approach to do Dependency Injection in Spring is constructor injection:在 Spring 中进行依赖注入的推荐方法是构造函数注入:
@Component
class YourBean(
private val mongoTemplate: MongoTemplate,
private val solrClient: SolrClient
) {
// code
}
Prior to Spring 4.3 constructor should be explicitly annotated with Autowired
:在 Spring 4.3 构造函数之前,应该使用
Autowired
显式注释:
@Component
class YourBean @Autowired constructor(
private val mongoTemplate: MongoTemplate,
private val solrClient: SolrClient
) {
// code
}
In rare cases, you might like to use field injection, and you can do it with the help of lateinit
:在极少数情况下,您可能喜欢使用字段注入,并且可以在
lateinit
的帮助下lateinit
:
@Component
class YourBean {
@Autowired
private lateinit var mongoTemplate: MongoTemplate
@Autowired
private lateinit var solrClient: SolrClient
}
Constructor injection checks all dependencies at bean creation time and all injected fields is val
, at other hand lateinit injected fields can be only var
, and have little runtime overhead.构造函数注入在 bean 创建时检查所有依赖项,所有注入的字段都是
val
,另一方面,lateinit 注入的字段只能是var
,并且几乎没有运行时开销。 And to test class with constructor, you don't need reflection.并且要使用构造函数测试类,您不需要反射。
Links:链接:
Yes, java annotations are supported in Kotlin mostly as in Java.是的,与 Java 一样,Kotlin 主要支持 Java 注释。 One gotcha is annotations on the primary constructor requires the explicit 'constructor' keyword:
一个问题是主构造函数上的注释需要显式的 'constructor' 关键字:
From https://kotlinlang.org/docs/reference/annotations.html来自https://kotlinlang.org/docs/reference/annotations.html
If you need to annotate the primary constructor of a class, you need to add the constructor keyword to the constructor declaration, and add the annotations before it:
如果需要对类的主构造函数进行注解,则需要在构造函数声明中添加constructor关键字,并在其前添加注解:
class Foo @Inject constructor(dependency: MyDependency) {
// ...
}
You can also autowire dependencies through the constructor.您还可以通过构造函数自动装配依赖项。 Remember to annotate your dependencies with
@Configuration, @Component, @Service
etc记得用
@Configuration, @Component, @Service
等注释你的依赖项
import org.springframework.stereotype.Component
@Component
class Foo (private val dependency: MyDependency) {
//...
}
像那样
@Component class Girl( @Autowired var outfit: Outfit)
If you want property injection but don't like lateinit var
, here is my solution using property delegate :如果您想要属性注入但不喜欢
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
}
Then you can use the much better by
delegate syntax:然后你可以
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.