解决Kotlin下使用@Transactional等Spring代理类空指针异常
直接上代码
open class BaseController<T : BaseEntity>(val baseService: BaseService<T>) {
@Transactional
@AuthRequired
@PatchMapping("/{id}")
open fun updateById(@PathVariable("id") id: Long, @RequestBody entity: T): ResponseEntity<T> {
entity.id = id
return ResponseEntity.ok(baseService.updateById(entity))
}
}
访问controller时出现NullPointerException,此时baseService为null
原因解析
Kotlin的字段和方法一样默认都是final,即无法被子类重写,所以意味着被编译为字节码后字段的getter和setter都是final的,无法被代理类重写,在调用时当然就会出现空指针
解决方案
为baseService添加修饰符open,即
open class BaseController<T : BaseEntity>(open val baseService: BaseService<T>) {
@Transactional
@AuthRequired
@PatchMapping("/{id}")
open fun updateById(@PathVariable("id") id: Long, @RequestBody entity: T): ResponseEntity<T> {
entity.id = id
return ResponseEntity.ok(baseService.updateById(entity))
}
}
事实上启用了kotlin-spring插件后,被@Component等注解修饰的类成员会自动为open状态,但是由于上述类为父类,未被注解修饰才发生这种情况