Question or issue of Kotlin Programming:
Is it possible to do something like following in Kotlin?
@Autowired internal var mongoTemplate: MongoTemplate @Autowired internal var solrClient: SolrClient
How to solve this issue?
Solution no. 1:
Recommended approach to do Dependency Injection in Spring is constructor injection:
@Component class YourBean( private val mongoTemplate: MongoTemplate, private val solrClient: SolrClient ) { // code }
Prior to Spring 4.3 constructor should be explicitly annotated with 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
:
@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. And to test class with constructor, you don’t need reflection.
Links:
- Documentation on lateinit
- Documentation on constructors
- Developing Spring Boot applications with Kotlin
Solution no. 2:
Yes, java annotations are supported in Kotlin mostly as in Java.
One gotcha is annotations on the primary constructor requires the explicit ‘constructor’ keyword:
From 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:
class Foo @Inject constructor(dependency: MyDependency) { // ... }
Solution no. 3:
You can also autowire dependencies through the constructor. Remember to annotate your dependencies with @Configuration, @Component, @Service
etc
import org.springframework.stereotype.Component @Component class Foo (private val dependency: MyDependency) { //... }
Solution no. 4:
like that
@Component class Girl( @Autowired var outfit: Outfit)