[英]Null Pointer Exception In Spring Proxy Class and Kotlin
我和kotlin一起面临春天的问题。
我有一个控制器bean(没有接口btw),它通过主构造函数有一个自动连接的服务bean。
除非我为控制器使用缓存注释,否则它工作正常。 显然,spring缓存会在引擎盖下生成一个代理类来处理缓存。
我的代码看起来像这样:
@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.service
为null
,这在技术上是不可能的,因为它是kotlin中的非null
变量。
我假设spring生成的类代理用null值而不是autowired bean初始化类。 这必须是使用kotlin和spring的常见陷阱。 你是怎么绕过这个问题的?
对于能够代理方法的代理库( CGLIB , javaassist ),它必须被声明为非final和非final类( 因为这些库通过子类实现代理 )。 将您的控制器方法更改为:
@RequestMapping("{id}", method = arrayOf(RequestMethod.GET))
@Cacheable(cacheNames = arrayOf("regions"))
open fun get(@PathVariable id: Long): RegionResource {
return this.service.get(id)
}
您可能会在控制台中看到有关RegionController
方法不受代理约束的警告。
Kotlin团队承认了这一困难并创建了一个插件,标志着标准的AOP代理候选者,例如@Component
with open
。
您可以在build.gradle
启用插件:
plugins {
id "org.jetbrains.kotlin.plugin.spring" version "1.1.60"
}
很快,这可能不再是一个问题。
正在进行的工作中,任何lib(包括spring)都可以在META-INF中指定文件的注释列表。 一旦用其中一个类注释了类,它将默认为类本身及其所有函数打开。 对于从带注释的类继承的类也是如此。
有关更多详细信息,请查看https://github.com/Kotlin/KEEP/pull/40#issuecomment-250773204
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.