Spring代理类和Kotlin中的空指针异常

我和春天一起面临着kotlin的一些问题。

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

它工作完美,除非我使用控制器缓存注释。 显然弹簧缓存生成一个委托类下的缓存处理。

我的代码如下所示:

@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中的非null变量。

我假设Spring生成的类代理使用空值而不是autowired bean初始化类。 这一定是使用kotlin和spring的常见错误。 你是怎么回避这个问题的?

在Kotlin中,两个类和成员都是默认最终的。

对于代理库( 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方法不受代理服务器的警告。

不久,这可能不再是一个问题。

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

有关详情,请参阅https://github.com/Kotlin/KEEP/pull/40#issuecomment-250773204