【问题标题】:Null Pointer Exception In Spring Proxy Class and KotlinSpring 代理类和 Kotlin 中的空指针异常
【发布时间】:2016-09-22 17:51:15
【问题描述】:

我在将 kotlin 与 spring 结合使用时遇到了一些问题。

我有一个控制器 bean(顺便说一句没有接口),它通过主构造函数有一个自动连接的服务 bean。

除非我为控制器使用缓存注释,否则它工作得很好。显然 springs 缓存会在后台生成一个代理类来处理缓存。

我的代码如下所示:

@RestController
@RequestMapping("/regions/")
open class RegionController @Autowired constructor(val service: RegionService) {
    @RequestMapping("{id}", method = arrayOf(RequestMethod.GET))
    @Cacheable(cacheNames = arrayOf("regions"))
    fun get(@PathVariable id: Long): RegionResource {
        return this.service.get(id)
    }
}

现在的问题是执行方法时出现空指针异常,实际上this.servicenull,这在技术上是不可能的,因为它是 kotlin 中的非空变量。

我假设class proxies generated by spring 使用空值而不是自动装配的 bean 来初始化类。这一定是使用 kotlin 和 spring 的常见陷阱。你是如何规避这个问题的?

【问题讨论】:

    标签: spring spring-mvc kotlin


    【解决方案1】:

    在 Kotlin 中默认为 classes and members are final

    为了让代理库(CGLIBjavaassist)能够代理方法,它必须声明为 non final 并在 non final 类中(since those libraries implement proxying by subclassing)。将您的控制器方法更改为:

    @RequestMapping("{id}", method = arrayOf(RequestMethod.GET))
    @Cacheable(cacheNames = arrayOf("regions"))
    open fun get(@PathVariable id: Long): RegionResource {
        return this.service.get(id)
    }
    

    您可能会在控制台中看到关于 RegionController 方法不受代理的警告。

    The Kotlin compiler plugin

    Kotlin 团队已经认识到这一困难,并创建了一个插件来标记标准 AOP 代理候选者,例如@Componentopen

    您可以通过build.gradle 启用插件:

    plugins {
      id "org.jetbrains.kotlin.plugin.spring" version "1.1.60"
    }
    

    【讨论】:

    • 这里值得一提:如果你有一个抽象类被一个带有@Component注解的类扩展,spring的kotlin插件默认不会打开抽象函数。子进程可以毫无问题地调用父进程,但如果外部调用父方法,它将查看所​​有空成员变量。在方法中添加open修复,或者在抽象类中添加spring注解,或者新建注解添加到kotlin-allopen插件中
    【解决方案2】:

    很快这可能不再是问题了。

    正在进行的工作是任何库(例如包括 spring)都可以在 META-INF 中指定一个文件的注释列表。一旦一个类被其中之一注释,它将默认为该类本身及其所有功能打开。对于从带注释的类继承的类也是如此。

    更多详情请关注https://github.com/Kotlin/KEEP/pull/40#issuecomment-250773204

    【讨论】:

    猜你喜欢
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多