Spring代理类和Kotlin中的空指针exception
我和spring一起面临着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) } }
现在的问题是执行该方法时出现空指针exception,实际上this.service
为null
,在技术上是不可能的,因为它是kotlin中的非null
variables。
我假设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
方法不受代理服务器的警告。
Kotlin编译器插件
Kotlin团队已经承认了这个难题,并创建了一个标准的AOP代理候选人(例如@Component
的插件。
你可以在你的build.gradle
启用这个插件:
plugins { id "org.jetbrains.kotlin.plugin.spring" version "1.1.60" }
不久,这可能不再是一个问题。
正在进行的工作中,任何lib(包括spring)都可以在META-INF中指定一个文件的注释列表。 一旦一个类被其中的一个注解,它将默认打开该类本身及其所有的function。 对于从注释类inheritance的类也是如此。
有关详情,请参阅https://github.com/Kotlin/KEEP/pull/40#issuecomment-250773204
- 如何定义一个调用枚举实例的xml配置spring bean?
- 春季数据JPA /hibernate“无法find给定名称的属性”
- Spring Boot + Kotlin AutoProxyRegistrar导致Nullpointerexception
- 部署java web应用程序.war文件后未find404
- Spring JPA无法在Kotlin数据类中使用自定义setter映射字段
- 从cmd运行时,Spring AOP不工作
- Spring Boot将文本/ JavaScript序列化为JSON
- IBM Bluemix Cloud Foundry SpringBoot kotlin应用程序错误
- Spring MVC控制器PathVariables上的Java beanvalidation