如何在Spring Boot中禁用spring-data-mongodb的自动配置

55

有人尝试禁用spring-boot中mongodb的自动配置吗?

我正在尝试使用基于Java的配置进行spring-boot和spring-data-mongodb的开发;使用spring-boot 1.2.1.RELEASE,并导入spring-boot-starter-web及其父POM以进行依赖管理。我还导入了spring-data-mongodb(尝试过spring-boot-starter-mongodb)。

我需要连接两个不同的MongoDB服务器。因此,我需要为mongo连接、MongoTemplate等配置两组实例。我还想禁用自动配置。由于我连接到多个服务器,所以不需要自动配置单个默认的MongoTemplate和GridFsTemplate bean。

我的主类如下:

@Configuration
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
@ComponentScan
//@SpringBootApplication  
public class MainRunner {

    public static void main(String[] args) {
        SpringApplication.run(MainRunner.class, args);
    }
}

我的两个MongoDB配置类看起来像这样:

@Configuration
@EnableMongoRepositories(basePackageClasses = {Test1Repository.class},
        mongoTemplateRef = "template1",
        includeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test1Repository")}
)
public class Mongo1Config {

    @Bean
    public Mongo mongo1() throws UnknownHostException {
        return new Mongo("localhost", 27017);
    }
    
    @Primary
    @Bean
    public MongoDbFactory mongoDbFactory1() throws UnknownHostException {
        return new SimpleMongoDbFactory(mongo1(), "test1");
    }

    @Primary
    @Bean
    public MongoTemplate template1() throws UnknownHostException {
        return new MongoTemplate(mongoDbFactory1());
    }
}

@Configuration
@EnableMongoRepositories(basePackageClasses = {Test2Repository.class},
        mongoTemplateRef = "template2",
        includeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test2Repository")}
)
public class Mongo2Config {
    
    @Bean
    public Mongo mongo2() throws UnknownHostException {
        return new Mongo("localhost", 27017);
    }
    
    @Bean
    public MongoDbFactory mongoDbFactory2() throws UnknownHostException {
        return new SimpleMongoDbFactory(mongo2(), "test2");
    }
    
    @Bean
    public MongoTemplate template2() throws UnknownHostException {
        return new MongoTemplate(mongoDbFactory2());
    }
}

使用这个配置,一切都正常。如果我从mongoDbFactory1和template1 bean中删除@Primary注解,则应用程序将失败,并出现一个异常消息,似乎自动配置没有被禁用。异常消息如下:

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
    at com.fourexpand.buzz.web.api.template.MainRunner.main(MainRunner.java:26)
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:98)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:75)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:378)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:155)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:157)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
    ... 7 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter': Injection of autowired dependencies failed; nested exception is  org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.core.io.ResourceLoader org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.resourceLoader; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gridFsTemplate' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoDataAutoConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.data.mongodb.MongoDbFactory]: : No qualifying bean of type [org.springframework.data.mongodb.MongoDbFactory] is defined: expected single matching bean but found 2: mongoDbFactory2,mongoDbFactory1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.data.mongodb.MongoDbFactory] is defined: expected single matching bean but found 2: mongoDbFactory2,mongoDbFactory1

1
дҪ жҳҜеҗҰжңүе…¶д»–дҪҝз”ЁдәҶSpringBootApplicationжҲ–EnableAutoConfigurationжіЁи§Јзҡ„зұ»пјҹ - Andy Wilkinson
4
尝试排除MongoRepositoriesAutoConfiguration - Artem Bilan
@AndyWilkinson,有点尴尬,我确实有另一个使用SpringBootApplication注释的类。我有多个入口点——用于测试的main方法和用于生产的Apache Daemon + jsvc运行器,我只是复制/粘贴了所有的注释,而没有将它们放到一个公共的地方...排除MongoRepositoriesAutoConfiguration最终证明是不必要的... - im__
我只想添加一点,MainRunner类中使用的注释帮助我尝试运行与两个数据库连接的Spring Boot应用程序,该应用程序的代码来自https://falkenfighter.wordpress.com/2015/10/13/multiple-databases-with-spring-boot-mongodb-repositories/。 - Francis Zabala
请排除EmbeddedMongoAutoConfiguration.class和EmbeddedMongoProperties.class。 - Antoine Wils
我的使用情况类似:我想在运行IDE时启用嵌入式MongoDB,但仅限于此。请注意,即使是使用自动配置的嵌入式MongoDB的方式也已经发生了变化自从Spring Boot 2.7以来。我撰写了一篇博客文章,其中包含了我在这里找到的一些指针以及其他一些有用的提示,题为Embedded MongoDB Only in IDE using Spring Boot 3.x - Garret Wilson
6个回答

48

这是我做的方法:

@SpringBootApplication(exclude = {
  MongoAutoConfiguration.class, 
  MongoDataAutoConfiguration.class
})

或者按照丹·奥克(Dan Oak)的建议:

spring.autoconfigure.exclude= \
  org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
  org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration

11

正如Andy Wilkinson在评论中指出的那样,当使用带有排除列表的EnableAutoConfiguration时,请确保没有其他类带有EnableAutoConfiguration或SpringBootApplication注释。


7

尝试以调试模式运行应用程序。当 MongoDB 依赖配置尝试实例化但相应的 bean 不存在时会发生这种情况。 在我的情况下,我排除了 MongoDataAutoConfiguration.class 和 MongoRepositoriesAutoConfiguration.class,以使应用程序运行。

@SpringBootApplication
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class,MongoDataAutoConfiguration.class})
public class SomeApplication {
//...
}

1
这对我有效。我必须将其放在 @SpringBootApplication 内部。 - Sovichea Cheth

7
我的使用场景略有不同。我在同一项目中需要使用两个不同的数据库。我扩展了自动配置类并添加了一个profile注解。
@Profile("mongo")
@Configuration
public class CustomMongoAutoConfiguration extends MongoAutoConfiguration {

    public CustomMongoAutoConfiguration(
        MongoProperties properties,
        ObjectProvider<MongoClientOptions> options,
        Environment environment) {
        super(properties,options,environment);
    }
}

并且

@Profile("mongo")
@Configuration
@EnableConfigurationProperties(MongoProperties.class)
public class CustomMongoDataAutoConfiguration extends MongoDataAutoConfiguration {

    public CustomMongoDataAutoConfiguration(
        ApplicationContext applicationContext,
        MongoProperties properties) {
        super(applicationContext,properties);
    }

}

我也有两个数据库,我可以确认这个方法可行。不需要更改Spring Boot应用程序的排除字段。这应该是真正的解决方案,因为其他方法对我来说似乎像是一个hack。我在设置两个数据库的Mongobee bean时遇到了问题,而这个方法解决了出现两个Mongobee bean的报告问题。 - edin-m
另外一点,我必须给Mongobee的bean起一个名称,否则它只会选择一个Mongobee。 - edin-m
我想只有一个配置,但只在特定的配置文件中启用它。使用新的 Spring 3 嵌入式 MongoDB,我仍然需要在我的主应用程序类中使用 @SpringBootApplication(exclude = {EmbeddedMongoAutoConfiguration.class}),否则会出现有关两次配置 bean 的错误,因为它还尝试注册底层的 EmbeddedMongoAutoConfiguration - Garret Wilson

3

Spring Boot 2.3.x:

spring.autoconfigure.exclude[0]: org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
spring.autoconfigure.exclude[1]: org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration

响应式编程:

spring.autoconfigure.exclude[0]: org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
spring.autoconfigure.exclude[1]: org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration

1

https://dev59.com/4l4b5IYBdhLWcg3wvT2w#45929916相同,使用https://dev59.com/4l4b5IYBdhLWcg3wvT2w#49980868,Spring Boot 2.3/Kotlin

@SpringBootApplication(exclude = [MongoAutoConfiguration::class, MongoDataAutoConfiguration::class]

@Profile("mongo")
@Configuration
class CustomMongoAutoConfiguration: MongoAutoConfiguration() {
    override fun mongo(
        properties: MongoProperties?,
        environment: Environment?,
        builderCustomizers: ObjectProvider<MongoClientSettingsBuilderCustomizer>?,
        settings: ObjectProvider<MongoClientSettings>?
    ): MongoClient {
        return super.mongo(properties, environment, builderCustomizers, settings)
    }
}

@Profile("mongo")
@Configuration
@EnableConfigurationProperties(MongoProperties::class)
class CustomMongoDataAutoConfiguration : MongoDataAutoConfiguration()

在Java中,可以通过@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})实现排除。 - Sebastián Rodriguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接