如何在 spring-boot 中禁用 spring-data-mongodb 自动配置

Posted

技术标签:

【中文标题】如何在 spring-boot 中禁用 spring-data-mongodb 自动配置【英文标题】:How to disable spring-data-mongodb autoconfiguration in spring-boot 【发布时间】:2015-04-29 03:39:04 【问题描述】:

有没有人试过在 spring-boot 中禁用 mongodb 的自动配置?

我正在尝试使用 spring-data-mongodb 的 spring-boot;使用基于java的配置;使用 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 // @Configuration @EnableAutoConfiguration @ComponentScan 
public class MainRunner 

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

我的两个 mongo 配置类如下所示:

@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

【问题讨论】:

你还有其他用SpringBootApplicationEnableAutoConfiguration注释的类吗? 也尝试排除MongoRepositoriesAutoConfiguration @AndyWilkinson 令人尴尬的是,我确实有另一个用 SpringBootApplication 注释的类。我有不止一个入口点 - main 用于测试和 Apache Daemon + jsvc runner 用于生产,我只是复制/粘贴所有注释而不是将它们放在一个共同的地方...排除 MongoRepositoriesAutoConfiguration 原来是没有必要的... 我只是想添加 MainRunner 类中使用的注释帮助我尝试使用来自 falkenfighter.wordpress.com/2015/10/13/… 的代码运行连接到两个数据库的弹簧启动 还排除 EmbeddedMongoAutoConfiguration.class 和 EmbeddedMongoProperties.class 【参考方案1】:

这就是我的做法:

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

或按照Dan Oak的建议:

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

我的用例略有不同。我在同一个项目中需要 2 个不同的数据库。我扩展了自动配置类并添加了配置文件注释。

@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 应用程序排除了必要的字段更改。这应该是真正的解决方案,因为另一个对我来说似乎是一个黑客。我在为两个数据库设置 Mongobee bean 时遇到问题,这解决了报告的两个可用 Mongobee bean 的问题。 另外注意,我必须给 Mongobee 的豆子起个名字,否则它只会捡到一个 Mongobee。【参考方案4】:

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

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

【讨论】:

这对我有用。我必须把它放在@SpringBootApplication【参考方案5】:

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

【讨论】:

【参考方案6】:

与https://***.com/a/45929916/5213837 和https://***.com/a/49980868/5213837 相同,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()

【讨论】:

以上是关于如何在 spring-boot 中禁用 spring-data-mongodb 自动配置的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用嵌入式数据库 Spring-boot spring-data-jpa

从 Spring-Boot 测试中排除 elasticsearchTemplate

如何通过依赖项禁用通过 spring.factories 注册的 spring 工厂并保留此 spring-boot 依赖项?

在 spring-boot 中禁用特定 url 的 Keycloak 身份验证

spring-boot结合maven配置不同环境的profile

如何在 Spring Boot pom.xml 中临时禁用依赖项 [关闭]