59

Has anyone tried disabling autoconfiguration for mongodb in spring-boot?

I am trying out spring-boot with spring-data-mongodb; Using java based configuration; Using spring-boot 1.2.1.RELEASE, I import spring-boot-starter-web and its' parent pom for dependency management. I also import spring-data-mongodb (tried spring-boot-starter-mongodb as well).

I need to connect to two different MongoDB servers. So I need to configure two sets of instances for mongo connection, MongoTemplate etc. I also want to disable auto-configuration. Since I am connecting to multiple servers, I don't need to have a single default MongoTemplate and GridFsTemplate bean autoconfigured.

My main class looks like this:

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

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

My two mongo configuration classes look like this:

@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());
    }
}

and

@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());
    }
}

With this setup everything works. If I remove @Primary annotations from mongoDbFactory1 and template1 beans, application will fail with an exception that seems like autoconfiguration hasn't been disabled. Exception message is listed below:

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
6
  • 1
    Do you have any other classes annotated with SpringBootApplication or EnableAutoConfiguration? Commented Feb 26, 2015 at 17:08
  • 4
    Try to exclude MongoRepositoriesAutoConfiguration as well. Commented Feb 26, 2015 at 17:13
  • @AndyWilkinson embarrassingly I did have another class annotated with SpringBootApplication. I had more than one entry point - main for testing and Apache Daemon + jsvc runner for production and I simply copy/pasted all the annotations instead of putting them to one common place... Excluding MongoRepositoriesAutoConfiguration turned out not to be necessary... Commented Feb 26, 2015 at 22:34
  • I just wanted to add that annotations used in the MainRunner class helped me trying to run a spring boot connected to two database using the code from falkenfighter.wordpress.com/2015/10/13/… Commented Apr 28, 2016 at 10:26
  • also exclude EmbeddedMongoAutoConfiguration.class and EmbeddedMongoProperties.class Commented May 18, 2016 at 15:46

6 Answers 6

56

This is how I do it:

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

or as suggested by Dan Oak:

spring.autoconfigure.exclude= \
  org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
  org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
Sign up to request clarification or add additional context in comments.

Comments

11

As pointed out by Andy Wilkinson in comments, when using EnableAutoConfiguration with exclude list make sure there are no other classes annotated with EnableAutoConfiguration or SpringBootApplication.

Comments

8

Try to Run application in Debug mode. It happens when MongoDB dependant configaration is trying to instantiate but respective bean not present. In My case I have excluded MongoDataAutoConfiguration.class and MongoRepositoriesAutoConfiguration.class, to get the application run.

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

1 Comment

This works for me. I have to put this inside @SpringBootApplication
7

My use case was slightly different. I had a requirement for 2 different databases in the same project. I extended the auto configuration classes and added a profile annotation.

@Profile("mongo")
@Configuration
public class CustomMongoAutoConfiguration extends MongoAutoConfiguration {

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

And

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

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

}

3 Comments

I have two dbs as well and I can confirm this works. No spring boot app excluded field changes necessary. This should be the real solution since the other seems like a hack to me. I had issues setting up Mongobee bean for two databases and this solved the reported issue of two Mongobee beans available.
Another note, I had to give Mongobee's beans a name otherwise, it picked up only one Mongobee.
I wanted to have just a single configuration, but to only enable it in a certain profile. Using the new Spring 3 embedded MongoDB, I still needed @SpringBootApplication(exclude = {EmbeddedMongoAutoConfiguration.class}) in my main application class or I would get an error about a bean being configured twice, as otherwise it tried to register the underlying EmbeddedMongoAutoConfiguration as well.
4

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

Reactive:

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

Comments

1

Same as https://stackoverflow.com/a/45929916/5213837 with https://stackoverflow.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()

1 Comment

In Java the exclution can be achieved with @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.