Spring Proxy类和Kotlin中的Null指针异常 [英] Null Pointer Exception In Spring Proxy Class and Kotlin
问题描述
我在春天与kotlin一起遇到一些问题.
I am facing some problems with kotlin in conjunction with spring.
我有一个控制器bean(没有接口btw),它具有通过主构造函数自动连接的服务bean.
I have a controller bean (without an interface btw) which has an auto-wired service bean via the primary constructor.
除非我对控制器使用了缓存注释,否则它会完美地工作.显然,spring缓存会在处理缓存的底层生成一个代理类.
It works perfectly unless I use caching annotations for the controller. Apparently springs caching generates a proxy class under the hood which deals with the caching.
我的代码如下:
@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中的非空变量.
The problem now is a null pointer exception when the method is executed, actually this.service
is null
which technically is not possible as it is a nonnull variable in kotlin.
我认为由spring生成的类代理使用空值而不是自动装配的bean初始化类.这一定是使用kotlin和spring的常见陷阱.您是如何规避这个问题的?
I assume that class proxies generated by spring initialize the class with null values instead of the autowired bean. This must be a common pitfall using kotlin and spring. How did you circumvent this problem?
推荐答案
在科特林,两个对于代理库( CGLIB ,,因为这些库通过子类).将您的控制器方法更改为:
For the proxying library (CGLIB, javaassist) to be able to proxy a method it has to be declared non final and in a non final class (since those libraries implement proxying by subclassing). Change your controller method to:
@RequestMapping("{id}", method = arrayOf(RequestMethod.GET))
@Cacheable(cacheNames = arrayOf("regions"))
open fun get(@PathVariable id: Long): RegionResource {
return this.service.get(id)
}
您可能会在控制台中看到有关RegionController
方法不受代理约束的警告.
You probably see a warning in console regarding RegionController
methods not being subject to proxying.
Kotlin团队已经意识到了这一困难,并创建了一个插件来标记标准AOP代理候选人,例如@Component
和open
.
The Kotlin team has acknowledged this difficulty and created a plugin that marks the standard AOP proxy candidates e.g. @Component
with open
.
您可以在build.gradle
中启用插件:
plugins {
id "org.jetbrains.kotlin.plugin.spring" version "1.1.60"
}
这篇关于Spring Proxy类和Kotlin中的Null指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!