Spring Boot 2.1 duplicate reactiveMongoTemplate bean

爱⌒轻易说出口 提交于 2019-12-08 02:22:14

问题


I have the following Spring Boot @Configuration class:

@Configuration
@EnableReactiveMongoRepositories
class MongoConfiguration : AbstractReactiveMongoConfiguration()
{
    override fun reactiveMongoClient() = MongoClients.create()

    override fun getDatabaseName() = "mydb"

    override fun customConversions(): MongoCustomConversions =
            MongoCustomConversions(listOf(ZonedDateTimeReadConverter(), ZonedDateTimeWriteConverter()))
}

The application fails to start, and logs this message:

The bean 'reactiveMongoTemplate', defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/mypackage/MongoConfiguration.class] and overriding is disabled.

This puzzles me, as the reactiveMongoTemplate ben method in MongoReactiveDataAutoConfiguration is configured with @ConditionalOnMissingBean.


回答1:


The problem is in AbstractReactiveMongoConfiguration that you have sub-classed. The signature of its reactiveMongoTemplate @Bean method states that it returns ReactiveMongoOperations. Until the bean has been created, that's all the type information that is available and there is no way for the bean factory to know that the bean is actually a ReactiveMongoTemplate instance. As a result, the @ConditionaOnMissingBean that's looking for a ReactiveMongoTemplate bean doesn't find one so an attempt to define both beans is made. This should be fixed in Spring Data MongoDB so that AbstractReactiveMongoConfiguration provides as much type information as possible for its beans. I've opened DATAMONGO-2355.

You can avoid the problem by making more use of Spring Boot's auto-configuration. Rather than sub-classing AbstractReactiveMongoConfiguration you can:

  1. Use the configuration property spring.data.mongodb.database=mydb to set the database.
  2. Use the auto-configured MongoClient bean rather than defining your own.
  3. Define your own MongoCustomConversions bean that will then be used in favour of one that Boot would otherwise auto-configure.



回答2:


As Andy's answer correctly points out, there is a mismatch between the return type of AbstractReactiveMongoConfiguration#reactiveMongoTemplate and the autoconfigured bean: the first one is ReactiveMongoOperations while the second one is ReactiveMongoTemplate. And as this happens to be the only type info available to the bean factory, the @ConditionalOnMissingBean has no effect.

So the problem goes away if I simply override AbstractReactiveMongoConfiguration#reactiveMongoTemplate to narrow the return type like this:

override fun reactiveMongoTemplate(): ReactiveMongoTemplate = 
        super.reactiveMongoTemplate() as ReactiveMongoTemplate

This is a hack though: the autoconfiguration should back out when any ReactiveMongoOperations bean is configured (for example, a stub).

So contrary to what Andy says, I believe the problem is not in AbstractReactiveMongoConfiguration but in MongoReactiveDataAutoConfiguration where the reactiveMongoTemplate bean method should be annotated with @ConditionalOnMissingBean(ReactiveMongoOperations.class).

This was probably forgotten because normally the actual bean will be a ReactiveMongoTemplate. But why have the ReactiveMongoOperations interface at all if it's not supported properly?



来源:https://stackoverflow.com/questions/57761228/spring-boot-2-1-duplicate-reactivemongotemplate-bean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!