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
- 即使使用jackson-datatype-jsr310,Instant也不能被序列化为适当的格式
- Angular:如何在表单提交中发布文件到服务器
- spring的数据mongodb和kotlin
- 无法通过Springboot连接到远程MongoDB
- Kotlin&Hibernate IllegalArgumentException:无法将字符串字段Job.name设置为Job
- 如何使用Spring Data JPA方法在Kotlin的try-with-resources块中返回Stream?
- Kotlin – 在SpringApplicationBuilder中传播运算符
- 如何定义一个调用枚举实例的xml配置spring bean?
- Mockito / Powermock不像Kotlin预期的那样工作