Autowiring a non-primitive with spring annotations like
@Autowired
lateinit var metaDataService: MetaDataService
works.
But this doesn't work:
@Value("\${cacheTimeSeconds}")
lateinit var cacheTimeSeconds: Int
with an error:
lateinit modifier is not allowed for primitive types.
How to autowire primitve properties into kotlin classes?
You can also use the @Value annotation within the constructor:
class Test(
@Value("\${my.value}")
private val myValue: Long
) {
//...
}
This has the benefit that your variable is final and none-nullable. I also prefer constructor injection. It can make testing easier.
@Value("\\${cacheTimeSeconds}") lateinit var cacheTimeSeconds: Int
should be
@Value("\${cacheTimeSeconds}")
val cacheTimeSeconds: Int? = null
I just used Number
instead of Int
like so...
@Value("\${cacheTimeSeconds}")
lateinit var cacheTimeSeconds: Number
The other options are to do what others mentioned before...
@Value("\${cacheTimeSeconds}")
var cacheTimeSeconds: Int? = null
Or you can simply provide a default value like...
@Value("\${cacheTimeSeconds}")
var cacheTimeSeconds: Int = 1
In my case I had to get a property that was a Boolean
type which is primitive in Kotlin, so my code looks like this...
@Value("\${myBoolProperty}")
var myBoolProperty: Boolean = false
Try to set a default value
@Value("\${a}")
val a: Int = 0
in application.properties
a=1
in the code
package com.example.demo
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.stereotype.Component
@SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
@Component
class Main : CommandLineRunner {
@Value("\${a}")
val a: Int = 0
override fun run(vararg args: String) {
println(a)
}
}
it will print 1
or use contructor inject
@Component
class Main(@Value("\${a}") val a: Int) : CommandLineRunner {
override fun run(vararg args: String) {
println(a)
}
}
The problem is not the annotation, but the mix of primitive and lateinit
, as per this question , Kotlin does not allow lateinit
primitives.
The fix would be to change to a nullable type Int?
, or to not use lateinit
.
This TryItOnline shows the issue.
Kotlin compiles Int to int in java code. Spring wanted non-primitive types for injection, so you should use Int? / Boolean? / Long? and etc. Nullable types kotlin compile to Integer / Boolean / etc.
From:
@Value("\${cacheTimeSeconds}") lateinit var cacheTimeSeconds: Int
To:
@delegate:Value("\${cacheTimeSeconds}") var cacheTimeSeconds by Delegates.notNull<Int>()
Good Luck
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.