From d549e6001a42b528b7458467ce19469649ea98af Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 22 Aug 2018 13:55:28 +0200 Subject: [PATCH 1/2] Add support for com.mongodb.client.MongoClient Next to com.mongodb.MongoClient the MongoDB Java driver offers the com.mongodb.client.MongoClient as entry point for database and collection operations. Spring Data MongoDB supports c.m.client.MongoClient via its MongoDbFactory using SimpleMongoClientDbFactory. The MongoAutoConfiguration now backs off if any of those two clients is already defined in the Application context allowing MongoDataAutoConfiguration to pick up the users driver implementation of choice. See gh-14176 --- .../mongo/MongoDataAutoConfiguration.java | 112 +++++++++++++++++- .../mongo/MongoAutoConfiguration.java | 3 +- .../MongoDataAutoConfigurationTests.java | 23 ++++ .../mongo/MongoAutoConfigurationTests.java | 23 ++++ 4 files changed, 155 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java index 9ff49965b9..58cda155f0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java @@ -16,27 +16,35 @@ package org.springframework.boot.autoconfigure.data.mongo; +import java.util.Arrays; +import java.util.List; + import com.mongodb.ClientSessionOptions; import com.mongodb.DB; import com.mongodb.MongoClient; import com.mongodb.client.ClientSession; import com.mongodb.client.MongoDatabase; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration.AnySyncMongoClientAvailable; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; @@ -63,11 +71,12 @@ import org.springframework.util.StringUtils; * @author Phillip Webb * @author EddĂș MelĂ©ndez * @author Stephane Nicoll + * @author Christoph Strobl * @since 1.1.0 */ @Configuration @ConditionalOnClass({ MongoClient.class, MongoTemplate.class }) -@ConditionalOnBean(MongoClient.class) +@Conditional(AnySyncMongoClientAvailable.class) @EnableConfigurationProperties(MongoProperties.class) @Import(MongoDataConfiguration.class) @AutoConfigureAfter(MongoAutoConfiguration.class) @@ -75,15 +84,22 @@ public class MongoDataAutoConfiguration { private final MongoProperties properties; - public MongoDataAutoConfiguration(MongoProperties properties) { + private final MongoDbFactoryFactory dbFactoryFactory; + + public MongoDataAutoConfiguration(ObjectProvider mongoClientProvider, + ObjectProvider mongoClientClientProvider, + MongoProperties properties) { + this.properties = properties; + this.dbFactoryFactory = new MongoDbFactoryFactory(mongoClientProvider, + mongoClientClientProvider); } @Bean + @Conditional(AnySyncMongoClientAvailable.class) @ConditionalOnMissingBean(MongoDbFactory.class) - public SimpleMongoDbFactory mongoDbFactory(MongoClient mongo) { - String database = this.properties.getMongoClientDatabase(); - return new SimpleMongoDbFactory(mongo, database); + public MongoDbFactory mongoDbFactory() { + return this.dbFactoryFactory.getFor(this.properties.getMongoClientDatabase()); } @Bean @@ -166,4 +182,90 @@ public class MongoDataAutoConfiguration { } + /** + * Check if either {@link com.mongodb.MongoClient} or + * {@link com.mongodb.client.MongoClient} is already defined in the + * {@link org.springframework.context.ApplicationContext}. + * + * @author Christoph Strobl + * @since 2.1 + */ + static class AnySyncMongoClientAvailable extends AnyNestedCondition { + + AnySyncMongoClientAvailable() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnBean(com.mongodb.MongoClient.class) + static class MongoClientPreferred { + + } + + @ConditionalOnBean(com.mongodb.client.MongoClient.class) + static class MongoClientClientPreferred { + + } + + } + + /** + * Encapsulation of {@link MongoDbFactory} creation depending on available beans + * {@link com.mongodb.MongoClient} or {@link com.mongodb.client.MongoClient} expressed + * via the given {@link ObjectProvider ObjectProviders}. Prefers the first available + * MongoDB client creating a suitable instance of {@link MongoDbFactory} for it. + * + * @author Christoph Strobl + * @since 2.1 + */ + static class MongoDbFactoryFactory { + + private final List> clientProviders; + + /** + * Create new instance of {@link MongoDbFactoryFactory}. + * @param clientProviders order matters here, as we choose the first available + * one. + */ + MongoDbFactoryFactory(ObjectProvider... clientProviders) { + this.clientProviders = Arrays.asList(clientProviders); + } + + /** + * Get the {@link MongoDbFactory} suitable for the first available MongoDB client. + * @param database the name of the default database to return on + * {@link MongoDbFactory#getDb()}. + * @return new instance of {@link MongoDbFactory} suitable for the first available + * MongoDB client. + */ + MongoDbFactory getFor(String database) { + + Object client = findAvailableClientProvider(); + + if (client instanceof MongoClient) { + return new SimpleMongoDbFactory(MongoClient.class.cast(client), database); + } + + if (client instanceof com.mongodb.client.MongoClient) { + return new SimpleMongoClientDbFactory( + com.mongodb.client.MongoClient.class.cast(client), database); + } + + return null; + } + + private Object findAvailableClientProvider() { + + for (ObjectProvider provider : this.clientProviders) { + Object client = provider.getIfAvailable(); + if (client != null) { + return client; + } + } + + throw new IllegalStateException( + "Expected to find at least one MongoDB client."); + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java index 659f709aa4..f93a7edb36 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java @@ -65,7 +65,8 @@ public class MongoAutoConfiguration { } @Bean - @ConditionalOnMissingBean + @ConditionalOnMissingBean(type = { "com.mongodb.MongoClient", + "com.mongodb.client.MongoClient" }) public MongoClient mongo() { this.mongo = this.factory.createMongoClient(this.options); return this.mongo; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java index 74ba12f9f9..a9e6f0b5cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.Set; import com.mongodb.MongoClient; +import com.mongodb.client.MongoClients; import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; @@ -39,7 +40,9 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; import org.springframework.data.mapping.model.FieldNamingStrategy; import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; +import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; @@ -173,6 +176,16 @@ public class MongoDataAutoConfigurationTests { .doesNotHaveBean(MongoDataAutoConfiguration.class)); } + @Test + public void createsMongoDbFactoryForMongoClientClientWhenBeanPresent() { + + this.contextRunner.withUserConfiguration(WithMongoClientClientConfiguration.class) + .run((context) -> { + MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); + assertThat(dbFactory).isInstanceOf(SimpleMongoClientDbFactory.class); + }); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) private static void assertDomainTypesDiscovered(MongoMappingContext mappingContext, Class... types) { @@ -197,6 +210,16 @@ public class MongoDataAutoConfigurationTests { } + @Configuration + static class WithMongoClientClientConfiguration { + + @Bean + com.mongodb.client.MongoClient mongoClient() { + return MongoClients.create(); + } + + } + private static class MyConverter implements Converter { @Override diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java index 884ccd8331..c2eb05a29b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java @@ -20,14 +20,17 @@ import javax.net.SocketFactory; import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; +import com.mongodb.client.MongoClients; import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; /** @@ -78,6 +81,17 @@ public class MongoAutoConfigurationTests { }); } + @Test + public void doesNotCreateMongoClientWhenAlreadyDefined() { + + this.contextRunner + .withPropertyValues("spring.data.mongodb.uri:mongodb://localhost/test") + .withUserConfiguration(ConfigurationWithClientMongoClient.class) + .run((context) -> assertThatExceptionOfType( + NoSuchBeanDefinitionException.class) + .isThrownBy(() -> context.getBean(MongoClient.class))); + } + @Configuration static class OptionsConfig { @@ -104,4 +118,13 @@ public class MongoAutoConfigurationTests { } + static class ConfigurationWithClientMongoClient { + + @Bean + com.mongodb.client.MongoClient mongoClient() { + return MongoClients.create(); + } + + } + } From 56329e67d73ba18130b852868d6580d3d082405b Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 28 Aug 2018 15:24:31 +0200 Subject: [PATCH 2/2] Polish "Add support for com.mongodb.client.MongoClient" Closes gh-14176 --- .../mongo/MongoDataAutoConfiguration.java | 114 ++++-------------- .../MongoDataAutoConfigurationTests.java | 16 ++- .../mongo/MongoAutoConfigurationTests.java | 16 ++- .../main/asciidoc/spring-boot-features.adoc | 4 + 4 files changed, 49 insertions(+), 101 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java index 58cda155f0..cfbe4b1b7a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java @@ -16,9 +16,6 @@ package org.springframework.boot.autoconfigure.data.mongo; -import java.util.Arrays; -import java.util.List; - import com.mongodb.ClientSessionOptions; import com.mongodb.DB; import com.mongodb.MongoClient; @@ -32,7 +29,7 @@ import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration.AnySyncMongoClientAvailable; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration.AnyMongoClientAvailable; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -43,6 +40,7 @@ import org.springframework.context.annotation.Import; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.core.MongoDbFactorySupport; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; @@ -75,8 +73,9 @@ import org.springframework.util.StringUtils; * @since 1.1.0 */ @Configuration -@ConditionalOnClass({ MongoClient.class, MongoTemplate.class }) -@Conditional(AnySyncMongoClientAvailable.class) +@ConditionalOnClass({ MongoClient.class, com.mongodb.client.MongoClient.class, + MongoTemplate.class }) +@Conditional(AnyMongoClientAvailable.class) @EnableConfigurationProperties(MongoProperties.class) @Import(MongoDataConfiguration.class) @AutoConfigureAfter(MongoAutoConfiguration.class) @@ -84,22 +83,25 @@ public class MongoDataAutoConfiguration { private final MongoProperties properties; - private final MongoDbFactoryFactory dbFactoryFactory; - - public MongoDataAutoConfiguration(ObjectProvider mongoClientProvider, - ObjectProvider mongoClientClientProvider, - MongoProperties properties) { - + public MongoDataAutoConfiguration(MongoProperties properties) { this.properties = properties; - this.dbFactoryFactory = new MongoDbFactoryFactory(mongoClientProvider, - mongoClientClientProvider); } @Bean - @Conditional(AnySyncMongoClientAvailable.class) @ConditionalOnMissingBean(MongoDbFactory.class) - public MongoDbFactory mongoDbFactory() { - return this.dbFactoryFactory.getFor(this.properties.getMongoClientDatabase()); + public MongoDbFactorySupport mongoDbFactory(ObjectProvider mongo, + ObjectProvider mongoClient) { + MongoClient preferredClient = mongo.getIfAvailable(); + if (preferredClient != null) { + return new SimpleMongoDbFactory(preferredClient, + this.properties.getMongoClientDatabase()); + } + com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable(); + if (fallbackClient != null) { + return new SimpleMongoClientDbFactory(fallbackClient, + this.properties.getMongoClientDatabase()); + } + throw new IllegalStateException("Expected to find at least one MongoDB client."); } @Bean @@ -183,87 +185,23 @@ public class MongoDataAutoConfiguration { } /** - * Check if either {@link com.mongodb.MongoClient} or - * {@link com.mongodb.client.MongoClient} is already defined in the - * {@link org.springframework.context.ApplicationContext}. - * - * @author Christoph Strobl - * @since 2.1 + * Check if either a {@link com.mongodb.MongoClient} or + * {@link com.mongodb.client.MongoClient} bean is available. */ - static class AnySyncMongoClientAvailable extends AnyNestedCondition { + static class AnyMongoClientAvailable extends AnyNestedCondition { - AnySyncMongoClientAvailable() { + AnyMongoClientAvailable() { super(ConfigurationPhase.REGISTER_BEAN); } - @ConditionalOnBean(com.mongodb.MongoClient.class) - static class MongoClientPreferred { + @ConditionalOnBean(MongoClient.class) + static class PreferredClientAvailable { } @ConditionalOnBean(com.mongodb.client.MongoClient.class) - static class MongoClientClientPreferred { - - } - - } - - /** - * Encapsulation of {@link MongoDbFactory} creation depending on available beans - * {@link com.mongodb.MongoClient} or {@link com.mongodb.client.MongoClient} expressed - * via the given {@link ObjectProvider ObjectProviders}. Prefers the first available - * MongoDB client creating a suitable instance of {@link MongoDbFactory} for it. - * - * @author Christoph Strobl - * @since 2.1 - */ - static class MongoDbFactoryFactory { - - private final List> clientProviders; - - /** - * Create new instance of {@link MongoDbFactoryFactory}. - * @param clientProviders order matters here, as we choose the first available - * one. - */ - MongoDbFactoryFactory(ObjectProvider... clientProviders) { - this.clientProviders = Arrays.asList(clientProviders); - } - - /** - * Get the {@link MongoDbFactory} suitable for the first available MongoDB client. - * @param database the name of the default database to return on - * {@link MongoDbFactory#getDb()}. - * @return new instance of {@link MongoDbFactory} suitable for the first available - * MongoDB client. - */ - MongoDbFactory getFor(String database) { - - Object client = findAvailableClientProvider(); - - if (client instanceof MongoClient) { - return new SimpleMongoDbFactory(MongoClient.class.cast(client), database); - } - - if (client instanceof com.mongodb.client.MongoClient) { - return new SimpleMongoClientDbFactory( - com.mongodb.client.MongoClient.class.cast(client), database); - } - - return null; - } - - private Object findAvailableClientProvider() { - - for (ObjectProvider provider : this.clientProviders) { - Object client = provider.getIfAvailable(); - if (client != null) { - return client; - } - } + static class FallbackClientAvailable { - throw new IllegalStateException( - "Expected to find at least one MongoDB client."); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java index a9e6f0b5cf..432f99c3db 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java @@ -43,6 +43,7 @@ import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; +import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; @@ -177,9 +178,16 @@ public class MongoDataAutoConfigurationTests { } @Test - public void createsMongoDbFactoryForMongoClientClientWhenBeanPresent() { + public void createsMongoDbFactoryForPreferredMongoClient() { + this.contextRunner.run((context) -> { + MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); + assertThat(dbFactory).isInstanceOf(SimpleMongoDbFactory.class); + }); + } - this.contextRunner.withUserConfiguration(WithMongoClientClientConfiguration.class) + @Test + public void createsMongoDbFactoryForFallbackMongoClient() { + this.contextRunner.withUserConfiguration(FallbackMongoClientConfiguration.class) .run((context) -> { MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); assertThat(dbFactory).isInstanceOf(SimpleMongoClientDbFactory.class); @@ -211,10 +219,10 @@ public class MongoDataAutoConfigurationTests { } @Configuration - static class WithMongoClientClientConfiguration { + static class FallbackMongoClientConfiguration { @Bean - com.mongodb.client.MongoClient mongoClient() { + com.mongodb.client.MongoClient fallbackMongoClient() { return MongoClients.create(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java index c2eb05a29b..b86757f853 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java @@ -23,14 +23,12 @@ import com.mongodb.MongoClientOptions; import com.mongodb.client.MongoClients; import org.junit.Test; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; /** @@ -83,13 +81,13 @@ public class MongoAutoConfigurationTests { @Test public void doesNotCreateMongoClientWhenAlreadyDefined() { - this.contextRunner .withPropertyValues("spring.data.mongodb.uri:mongodb://localhost/test") - .withUserConfiguration(ConfigurationWithClientMongoClient.class) - .run((context) -> assertThatExceptionOfType( - NoSuchBeanDefinitionException.class) - .isThrownBy(() -> context.getBean(MongoClient.class))); + .withUserConfiguration(FallbackMongoClientConfig.class).run((context) -> { + assertThat(context).doesNotHaveBean(MongoClient.class); + assertThat(context) + .hasSingleBean(com.mongodb.client.MongoClient.class); + }); } @Configuration @@ -118,10 +116,10 @@ public class MongoAutoConfigurationTests { } - static class ConfigurationWithClientMongoClient { + static class FallbackMongoClientConfig { @Bean - com.mongodb.client.MongoClient mongoClient() { + com.mongodb.client.MongoClient fallbackMongoClient() { return MongoClients.create(); } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 9b2cd91524..38bbfe6e58 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4029,6 +4029,10 @@ example, you might declare the following settings in your `application.propertie spring.data.mongodb.port=27017 ---- +If you have defined your own `MongoClient`, it will be used to auto-configure a suitable +`MongoDbFactory`. Both `com.mongodb.MongoClient` and `com.mongodb.client.MongoClient` +are supported. + NOTE: If you use the Mongo 3.0 Java driver, `spring.data.mongodb.host` and `spring.data.mongodb.port` are not supported. In such cases, `spring.data.mongodb.uri` should be used to provide all of the configuration.