代码之家  ›  专栏  ›  技术社区  ›  Irios

springkotlin:Bean字段在运行时为空,尽管在实例化期间被注入

  •  0
  • Irios  · 技术社区  · 6 年前

    我正在尝试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://localhost:8080/group/create]
    
    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应用程序中实现这个模式没有问题。

    谢谢!

    0 回复  |  直到 6 年前