Merge pull request #14176 from christophstrobl

* pr/14176:
  Polish "Add support for com.mongodb.client.MongoClient"
  Add support for com.mongodb.client.MongoClient
pull/14215/merge
Stephane Nicoll 6 years ago
commit 90b8578e0a

@ -22,21 +22,27 @@ import com.mongodb.MongoClient;
import com.mongodb.client.ClientSession; import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoDatabase;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 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.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration.AnyMongoClientAvailable;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.MongoDbFactory; 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.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
@ -63,11 +69,13 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb * @author Phillip Webb
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Christoph Strobl
* @since 1.1.0 * @since 1.1.0
*/ */
@Configuration @Configuration
@ConditionalOnClass({ MongoClient.class, MongoTemplate.class }) @ConditionalOnClass({ MongoClient.class, com.mongodb.client.MongoClient.class,
@ConditionalOnBean(MongoClient.class) MongoTemplate.class })
@Conditional(AnyMongoClientAvailable.class)
@EnableConfigurationProperties(MongoProperties.class) @EnableConfigurationProperties(MongoProperties.class)
@Import(MongoDataConfiguration.class) @Import(MongoDataConfiguration.class)
@AutoConfigureAfter(MongoAutoConfiguration.class) @AutoConfigureAfter(MongoAutoConfiguration.class)
@ -81,9 +89,19 @@ public class MongoDataAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(MongoDbFactory.class) @ConditionalOnMissingBean(MongoDbFactory.class)
public SimpleMongoDbFactory mongoDbFactory(MongoClient mongo) { public MongoDbFactorySupport<?> mongoDbFactory(ObjectProvider<MongoClient> mongo,
String database = this.properties.getMongoClientDatabase(); ObjectProvider<com.mongodb.client.MongoClient> mongoClient) {
return new SimpleMongoDbFactory(mongo, database); 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 @Bean
@ -166,4 +184,26 @@ public class MongoDataAutoConfiguration {
} }
/**
* Check if either a {@link com.mongodb.MongoClient} or
* {@link com.mongodb.client.MongoClient} bean is available.
*/
static class AnyMongoClientAvailable extends AnyNestedCondition {
AnyMongoClientAvailable() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnBean(MongoClient.class)
static class PreferredClientAvailable {
}
@ConditionalOnBean(com.mongodb.client.MongoClient.class)
static class FallbackClientAvailable {
}
}
} }

@ -65,7 +65,8 @@ public class MongoAutoConfiguration {
} }
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean(type = { "com.mongodb.MongoClient",
"com.mongodb.client.MongoClient" })
public MongoClient mongo() { public MongoClient mongo() {
this.mongo = this.factory.createMongoClient(this.options); this.mongo = this.factory.createMongoClient(this.options);
return this.mongo; return this.mongo;

@ -21,6 +21,7 @@ import java.util.Arrays;
import java.util.Set; import java.util.Set;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.mongodb.client.MongoClients;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
@ -39,7 +40,10 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
import org.springframework.data.mapping.model.FieldNamingStrategy; import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; 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.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.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@ -173,6 +177,23 @@ public class MongoDataAutoConfigurationTests {
.doesNotHaveBean(MongoDataAutoConfiguration.class)); .doesNotHaveBean(MongoDataAutoConfiguration.class));
} }
@Test
public void createsMongoDbFactoryForPreferredMongoClient() {
this.contextRunner.run((context) -> {
MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class);
assertThat(dbFactory).isInstanceOf(SimpleMongoDbFactory.class);
});
}
@Test
public void createsMongoDbFactoryForFallbackMongoClient() {
this.contextRunner.withUserConfiguration(FallbackMongoClientConfiguration.class)
.run((context) -> {
MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class);
assertThat(dbFactory).isInstanceOf(SimpleMongoClientDbFactory.class);
});
}
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private static void assertDomainTypesDiscovered(MongoMappingContext mappingContext, private static void assertDomainTypesDiscovered(MongoMappingContext mappingContext,
Class<?>... types) { Class<?>... types) {
@ -197,6 +218,16 @@ public class MongoDataAutoConfigurationTests {
} }
@Configuration
static class FallbackMongoClientConfiguration {
@Bean
com.mongodb.client.MongoClient fallbackMongoClient() {
return MongoClients.create();
}
}
private static class MyConverter implements Converter<MongoClient, Boolean> { private static class MyConverter implements Converter<MongoClient, Boolean> {
@Override @Override

@ -20,6 +20,7 @@ import javax.net.SocketFactory;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions; import com.mongodb.MongoClientOptions;
import com.mongodb.client.MongoClients;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -78,6 +79,17 @@ public class MongoAutoConfigurationTests {
}); });
} }
@Test
public void doesNotCreateMongoClientWhenAlreadyDefined() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri:mongodb://localhost/test")
.withUserConfiguration(FallbackMongoClientConfig.class).run((context) -> {
assertThat(context).doesNotHaveBean(MongoClient.class);
assertThat(context)
.hasSingleBean(com.mongodb.client.MongoClient.class);
});
}
@Configuration @Configuration
static class OptionsConfig { static class OptionsConfig {
@ -104,4 +116,13 @@ public class MongoAutoConfigurationTests {
} }
static class FallbackMongoClientConfig {
@Bean
com.mongodb.client.MongoClient fallbackMongoClient() {
return MongoClients.create();
}
}
} }

@ -4029,6 +4029,10 @@ example, you might declare the following settings in your `application.propertie
spring.data.mongodb.port=27017 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 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` `spring.data.mongodb.port` are not supported. In such cases, `spring.data.mongodb.uri`
should be used to provide all of the configuration. should be used to provide all of the configuration.

Loading…
Cancel
Save