我正在尝试SpringKotlin支持,我希望在SpringBoot应用程序中实现以下简单的DAO模式(使用SpringReactive特性,由SpringInitializer网站生成):
@Document
data class Person(val age: Int, val name: String)
abstract class AbstractDAO<T>(private val clazz: Class<T>, private val reactiveMongoTemplate: ReactiveMongoTemplate) {
fun create(t: Mono<T>) = reactiveMongoTemplate.insert(t)
fun findAll() = reactiveMongoTemplate.findAll(clazz)
}
@Repository
class GroupDAO(reactiveMongoTemplate: ReactiveMongoTemplate) : AbstractDAO<Group>(Group::class.java, reactiveMongoTemplate)
@RestController
@RequestMapping("/group")
class GroupController(val groupDao: GroupDAO) {
@PostMapping("/create")
fun create(@RequestBody group: Mono<Group>) = groupDao.create(group)
}
以下是相关的stacktrace:
2018-10-02 10:07:51.294 INFO 19434 --- [-server-epoll-5] r.ipc.netty.tcp.BlockingNettyContext : Started HttpServer on /0:0:0:0:0:0:0:0%0:8080
2018-10-02 10:07:51.294 INFO 19434 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
2018-10-02 10:07:51.295 DEBUG 19434 --- [ main] s.b.w.r.c.StandardReactiveWebEnvironment : Adding PropertySource 'server.ports' with highest search precedence
2018-10-02 10:07:51.298 INFO 19434 --- [ main] fr.rs.reactive.ReactiveApplicationKt : Started ReactiveApplicationKt in 7.284 seconds (JVM running for 8.072)
2018-10-02 10:08:06.655 ERROR 19434 --- [-server-epoll-7] .a.w.r.e.DefaultErrorWebExceptionHandler : Failed to handle request [POST http:
java.lang.NullPointerException: null
at fr.rs.reactive.dao.AbstractDAO.create(AbstractDAO.kt:7) ~[classes/:na]
at fr.rs.reactive.web.GroupController.create(GroupController.kt:19) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:243) ~[spring-webflux-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$invoke$0(InvocableHandlerMethod.java:138) ~[spring-webflux-5.0.9.RELEASE.jar:5.0.9.RELEASE]
AbstractDAO类中的ligne 7是这样的:
fun create(t: Mono<T>) = reactiveMongoTemplate.insert(t)
这段代码编译后,我的应用程序启动并运行,但是发生了以下行为,当实际调用insert或findAll方法时,我得到了NullPointerException。以下是我的观察结果:
-
当我在AbstractDAO类的类行上放置断点时,reactiveMongoInstance被正确注入->notnull
-
当我在用@PostConstruct注释的方法中放置断点时,reactiveMongoInstance字段被正确初始化
-
Spring创建的GroupDAO实例在作为另一个类(例如控制器)的构造函数参数提供时被正确地注入
-
当从控制器调用GroupDAO实例的方法时,会发生NullPointerException:clazz和reactiveMongoTemplate都为null
-
在构造函数和@PostConstruct方法中,调试器显示的GroupDAO实例似乎是一个“普通”实例,而注入控制器的实例是一个Spring增强的实例(CGLIB)
你知道为什么增强的实例字段在启动时被正确注入,但在运行时却为空吗?你认为这与我的应用程序是一个“被动”的应用程序有关吗?还是和科特林有关?我在基于java的非反应式Spring-boot应用程序中实现这个模式没有问题。
谢谢!