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 // @Configuration @EnableAutoConfiguration @ComponentScan 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
If you find that specific auto-configure classes are being applied that you don't want, you can use the exclude attribute of @EnableAutoConfiguration to disable them. If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead.
Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With