如何在 Kotlin 中使用 Spring 注解,例如 @Autowired 或 @Value,用于原始类型?

44
使用以下类似的Spring注解自动装配非原始类型是有效的:
@Autowired
lateinit var metaDataService: MetaDataService

但这不起作用:

@Value("\${cacheTimeSeconds}")
lateinit var cacheTimeSeconds: Int

错误:

原始类型不允许使用lateinit修饰符。

如何将原始属性自动装配到Kotlin类中?


你能自动装配可空版本吗?这个字段必须是延迟初始化的吗? - jrtapsell
1
是的,var todCacheTimeSeconds: Int? = null 是可行的,但这不是我想要的。 - fkurth
7个回答

49

您还可以在构造函数中使用@Value注释:

class Test(
    @Value("\${my.value}")
    private val myValue: Long
) {
        //...
  }

这样做的好处是您的变量是final和非空的。我也更喜欢构造函数注入。它可以使测试变得更容易。


21

@Value("\${cacheTimeSeconds}") lateinit var cacheTimeSeconds: Int

@Value("\${cacheTimeSeconds}")
val cacheTimeSeconds: Int? = null

还可以通过在env中注入并从那里传递值,使用lazy委托。 - qwert_ukg
3
如果可能的话,我建议不要使用可空类型(这不仅仅是因为OP说这不是一个选项)。将本来不打算设计成可空的东西变成可空的,基本上就像是倒退到Java... - milosmns

12

我刚刚使用了Number而不是Int,就像这样:

@Value("\${cacheTimeSeconds}")
lateinit var cacheTimeSeconds: Number

其他选项是做别人之前提到过的:
@Value("\${cacheTimeSeconds}")
var cacheTimeSeconds: Int? = null

或者您可以简单地提供一个默认值,例如:

@Value("\${cacheTimeSeconds}")
var cacheTimeSeconds: Int = 1

在我的情况下,我需要获取一个在 Kotlin 中是原始类型的 Boolean 属性,因此我的代码如下所示:
@Value("\${myBoolProperty}")
var myBoolProperty: Boolean = false

3
尝试设置默认值。
    @Value("\${a}")
    val a: Int = 0

在 application.properties 文件中。
a=1

在代码中
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)
    }
}

它将会输出1

或者使用构造函数注入

@Component
class Main(@Value("\${a}") val a: Int) : CommandLineRunner {

    override fun run(vararg args: String) {
        println(a)
    }
}

1

没有默认值和构造函数外部

来自:

@Value("\${cacheTimeSeconds}") lateinit var cacheTimeSeconds: Int

至:

@delegate:Value("\${cacheTimeSeconds}")  var cacheTimeSeconds by Delegates.notNull<Int>()

祝你好运

Kotlin没有原始类型


1
OP说:“使用Spring注释自动装配非原始类型”... - powermilk
@powermilk,你能分享一下相关属性,以便我们尝试推断为什么会失败或者重现这个问题吗?同时也请提供完整的错误信息。 - Braian Coronel
1
字符串是对象,而不是原始类型。我知道,在 Kotlin 中只有对象,但在 JVM 中不是这样。请参考 OP 中的示例:@Value("\${cacheTimeSeconds}") lateinit var cacheTimeSeconds: Int本主题中提供了一些解决方案,但如果没有默认值并且在构造函数之外,您可以按照以下方式执行:@delegate:Value("\${cacheTimeSeconds}") var cacheTimeSeconds by Delegates.notNull<Int>() - powermilk
更新的答案。谢谢。 - Braian Coronel

0
问题不在于注释,而是原始类型和lateinit的混合使用,根据this question,Kotlin不允许使用lateinit原始类型。
解决方法是将其更改为可空类型Int?,或者不使用lateinit这个TryItOnline展示了这个问题。

0

Kotlin 在 Java 代码中将 Int 编译为int。Spring 希望用于注入的不是原始类型,因此你应该使用 Int? / Boolean? / Long? 等可为空类型。Kotlin 中的可空类型编译为 Integer / Boolean / 等等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接