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

Spring Boot中RequestScope Bean属性为Null的Kotlin问题

Kotlin实现RequestScope Bean时属性获取为null的问题

环境

  • Spring Boot 2.7.2
  • Kotlin: 221-1.7.10-release-333-IJ5591.52

复现代码

@SpringBootApplication
class AbcApplication

fun main(args: Array<String>) {
    runApplication<AbcApplication>(*args)
}

@RestController
class Home(val importantContext: ImportantContext) {

    @GetMapping
    fun index(): Any {
        return "toString: '${importantContext}' VS message: '${importantContext.importantMessage}'";
    }
}

@Configuration
class ImportantConfiguration {

    @Bean
    @RequestScope
    fun importantContext(): ImportantContext {
        return ImportantContext("important content")
    }

}

open class ImportantContext(var importantMessage: String?) {

    override fun toString(): String {
        return "ImportantContext(importantMessage=$importantMessage)"
    }
}

问题现象

调用GET http://localhost:8080 返回结果:

toString: 'ImportantContext(importantMessage=important content)' VS message: 'null'

预期属性importantMessage的值应与toString输出一致,但实际获取为null。改用Java实现ImportantContext后可正常获取属性值。

原因分析

这是Spring作用域代理机制导致的:

  • 标记@RequestScope的Bean会被Spring生成CGLIB代理类,代理类继承原类,用于在请求作用域内管理Bean实例。
  • Kotlin中,即使类被标记为open,类内var/val属性的getter/setter方法默认是final的,无法被CGLIB代理类重写。
  • 直接访问importantMessage属性时,调用的是代理类的final getter方法,而代理类自身未初始化该属性,因此返回null。
  • toString()方法被显式override,属于open方法,代理类可重写它,最终会调用真实Bean实例的toString方法,因此能显示正确值。

解决方案

给ImportantContext类的importantMessage属性添加open修饰符,让其getter方法变为可重写,CGLIB代理就能正确转发属性访问到真实Bean实例:

open class ImportantContext(open var importantMessage: String?) {

    override fun toString(): String {
        return "ImportantContext(importantMessage=$importantMessage)"
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:27:36