未生成 Spring ReactiveMongoRepository bean

Posted

技术标签:

【中文标题】未生成 Spring ReactiveMongoRepository bean【英文标题】:Spring ReactiveMongoRepository bean not generated 【发布时间】:2019-08-08 21:04:36 【问题描述】:

我对 Java 和 Spring 很陌生,这是我的第一个 Kotlin 应用程序,所以我的问题可能是第 8 层(我)。但我真的不知道我做错了什么。根据本教程 (https://www.baeldung.com/kotlin-mongodb-spring-webflux) 这应该可以工作。

我的一般应用程序设置是控制器 --> 服务 --> 存储库(我没有添加控制器,因为这不是问题)。我的问题是工厂无法创建Repository Bean。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'driveController' defined in file [/Users/sburger/Documents/Dev/Gravity/App Framework/bouncr/build/classes/kotlin/main/de/example/drive/controller/DriveController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'driveService' defined in file [/Users/sburger/Documents/Dev/Gravity/App Framework/bouncr/build/classes/kotlin/main/de/example/drive/service/DriveService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'IBookingsRepository': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: kotlin/reflect/full/KClasses
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1325) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1171) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:67) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at de.example.AppKt.main(App.kt:14) ~[main/:na]
    at de.example.AppKt.main(App.kt) ~[main/:na]

App.kt

@SpringBootApplication(exclude = [MongoReactiveDataAutoConfiguration::class])
open class App

fun main() 
    runApplication<App>()

MongoConfig.kt

@Configuration
@EnableReactiveMongoRepositories(basePackageClasses = [IBookingsRepository::class])
open class MongoConfig : AbstractReactiveMongoConfiguration() 
    override fun getDatabaseName() = "exampledb"

    override fun reactiveMongoClient() = mongoClient()

    @Bean
    override fun reactiveMongoTemplate() = ReactiveMongoTemplate(mongoClient(), databaseName)

    @Bean
    open fun mongoClient(): MongoClient = MongoClients.create()


我不得不将课程和乐趣标记为“开放”。没有它,构建不起作用。这已经与教程不同了。

DriveService.kt

interface IDriveService 
    fun getBookings(userId: String) : Flux<Booking>


@Service
class DriveService @Autowired constructor(private val bookingsRepository: IBookingsRepository) :
    IBookingService 
    override fun getBookings(userId: String): Flux<Booking> 
       return bookingsRepository.findAll()
    

“findAll()”方法继承自 ReactiveMongoRepository

BookingsRepository.kt

interface IBookingsRepository : ReactiveMongoRepository<Booking, String>

这个接口明明没有init函数,教程里也没有。所以我认为它应该按原样工作?

有人提示此设置可能有什么问题吗?

【问题讨论】:

为什么要排除自动配置? Spring Boot 将自动为您配置所有这些。 另外,请发布完整的例外,而不仅仅是一个 sn-p。 堆栈跟踪非常清晰。至少java.lang.NoClassDefFoundError: kotlin/reflect/full/KClasses 应该给你一个关于哪里出了问题的提示。 @M.Deinum 感谢您的快速回复。其实我不确定。我检查了本教程的源代码 (github.com/eugenp/tutorials/blob/master/spring-5-data-reactive/…),他们也这样做了。如果我删除它,我会收到此错误在类路径资源 [.../mongo/MongoReactiveDataAutoConfiguration.class] 中定义的 bean 'reactiveMongoTemplate' 无法注册。已在类路径资源 [.../config/MongoConfig.class] 中定义了具有该名称的 bean,并且已禁用覆盖。 好的,我必须添加“kotlin-reflect”作为依赖项。我仍然有问题,但至少我更进一步。谢谢@M.Deinum 【参考方案1】:

这里有几个问题:

    您需要将依赖项添加到org.jetbrains.kotlin:kotlin-reflect。如果您在https://start.spring.io/ 生成 Kotlin 项目,它应该会自动添加。

    Baeldung 教程很糟糕。他们排除了自动配置 没有理由,或者至少没有解释原因。 Spring Boot 是关于 Convention Over Configuration 所以默认应该是使用 尽可能多的自动配置。

    正如您在 cmets 中所指出的,不排除自动配置会导致异常。这是由于 Spring Data MongoDb 中的一个错误,最近由于 this question 而打开了票证 DATAMONGO-2355。

    然而,在这种情况下,正确的解决方案不是排除自动配置,而是更多地使用它。这里没有理由扩展AbstractReactiveMongoConfiguration。正如this answer 中解释的那样,您可以通过属性配置数据库名称,并将所有其他内容保持自动配置。如果您出于某种原因需要扩展 AbstractReactiveMongoConfiguration,在修复错误之前,您可以覆盖 reactiveMongoTemplate() 方法以将返回类型缩小为 ReactiveMongoTemplate,如 this answer 中所述。

【讨论】:

以上是关于未生成 Spring ReactiveMongoRepository bean的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 中成功身份验证后未生成 JWT 令牌

Spring 应用程序未考虑 spring.schemas

在 Spring Boot 应用程序的 log4j2 中未生成日志文件

Hibernate 逆向工程未生成正确的域代码 STS

Spring Security 未创建 CSRF 令牌

Spring Boot application.properties 值未填充且未读取