You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot Kotlin读取application.yaml变量报错:lateinit属性未初始化

Kotlin中@ConfigurationProperties配合伴生对象导致未初始化的问题分析与解决

你碰到的这个lateinit property has not been initialized错误,核心原因是Spring的@ConfigurationProperties机制无法自动注入伴生对象(companion object)里的静态属性,让我给你拆解一下:

问题根源

Spring的@ConfigurationProperties是专门用来绑定配置到类的实例属性上的,而companion object属于类的静态成员范畴——Spring容器只会处理类的实例属性的注入,完全不会识别或处理静态属性。

你把value和result放在companion object里,当Spring初始化NumError这个Bean的时候,只会扫描类的非静态属性并绑定配置值,伴生对象里的变量根本不会被触及,所以这些lateinit变量一直处于未初始化状态,调用时自然就抛出kotlin.UninitializedPropertyAccessException了。

正确的解决方式

方式1:遵循Spring设计规范(推荐)

去掉companion object,直接把配置属性定义为类的实例属性,然后通过依赖注入的方式访问:

@ConfigurationProperties(prefix = "num_error")
@Component
class NumError {
    lateinit var value: String
    lateinit var result: Number
}

在需要使用的地方,通过构造注入获取NumError的实例:

@Service
class YourBusinessService(
    // 构造注入NumError实例
    private val numError: NumError
) {
    fun someBusinessLogic() {
        println("配置的value是:${numError.value}")
        println("配置的result是:${numError.result}")
    }
}

这种方式完全符合Spring的依赖注入设计,代码更易测试、维护,也不会有静态变量带来的潜在问题。

方式2:特殊场景下的静态访问(不推荐)

如果因为某些历史原因必须用静态方式访问配置,可以通过@PostConstruct注解,在Bean初始化完成后手动把实例属性的值赋值给伴生对象的静态变量:

@ConfigurationProperties(prefix = "num_error")
@Component
class NumError {
    // 实例属性,用于Spring绑定配置
    lateinit var value: String
    lateinit var result: Number

    companion object {
        // 静态变量,供外部静态访问
        lateinit var staticValue: String
        lateinit var staticResult: Number
    }

    // Bean初始化完成后执行,把实例属性的值同步到静态变量
    @PostConstruct
    fun syncStaticProperties() {
        staticValue = this.value
        staticResult = this.result
    }
}

之后你就可以通过NumError.staticValue来访问配置值了,但这种方式会破坏依赖注入的封装性,尽量少用。

内容的提问来源于stack exchange,提问作者has400

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:52:53