Skip to content

Commit 56329e6

Browse files
committed
Polish "Add support for com.mongodb.client.MongoClient"
Closes gh-14176
1 parent d549e60 commit 56329e6

File tree

4 files changed

+49
-101
lines changed

4 files changed

+49
-101
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java

Lines changed: 26 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616

1717
package org.springframework.boot.autoconfigure.data.mongo;
1818

19-
import java.util.Arrays;
20-
import java.util.List;
21-
2219
import com.mongodb.ClientSessionOptions;
2320
import com.mongodb.DB;
2421
import com.mongodb.MongoClient;
@@ -32,7 +29,7 @@
3229
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3330
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3431
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
35-
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration.AnySyncMongoClientAvailable;
32+
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration.AnyMongoClientAvailable;
3633
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
3734
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
3835
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -43,6 +40,7 @@
4340
import org.springframework.dao.DataAccessException;
4441
import org.springframework.dao.support.PersistenceExceptionTranslator;
4542
import org.springframework.data.mongodb.MongoDbFactory;
43+
import org.springframework.data.mongodb.core.MongoDbFactorySupport;
4644
import org.springframework.data.mongodb.core.MongoTemplate;
4745
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;
4846
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
@@ -75,31 +73,35 @@
7573
* @since 1.1.0
7674
*/
7775
@Configuration
78-
@ConditionalOnClass({ MongoClient.class, MongoTemplate.class })
79-
@Conditional(AnySyncMongoClientAvailable.class)
76+
@ConditionalOnClass({ MongoClient.class, com.mongodb.client.MongoClient.class,
77+
MongoTemplate.class })
78+
@Conditional(AnyMongoClientAvailable.class)
8079
@EnableConfigurationProperties(MongoProperties.class)
8180
@Import(MongoDataConfiguration.class)
8281
@AutoConfigureAfter(MongoAutoConfiguration.class)
8382
public class MongoDataAutoConfiguration {
8483

8584
private final MongoProperties properties;
8685

87-
private final MongoDbFactoryFactory dbFactoryFactory;
88-
89-
public MongoDataAutoConfiguration(ObjectProvider<MongoClient> mongoClientProvider,
90-
ObjectProvider<com.mongodb.client.MongoClient> mongoClientClientProvider,
91-
MongoProperties properties) {
92-
86+
public MongoDataAutoConfiguration(MongoProperties properties) {
9387
this.properties = properties;
94-
this.dbFactoryFactory = new MongoDbFactoryFactory(mongoClientProvider,
95-
mongoClientClientProvider);
9688
}
9789

9890
@Bean
99-
@Conditional(AnySyncMongoClientAvailable.class)
10091
@ConditionalOnMissingBean(MongoDbFactory.class)
101-
public MongoDbFactory mongoDbFactory() {
102-
return this.dbFactoryFactory.getFor(this.properties.getMongoClientDatabase());
92+
public MongoDbFactorySupport<?> mongoDbFactory(ObjectProvider<MongoClient> mongo,
93+
ObjectProvider<com.mongodb.client.MongoClient> mongoClient) {
94+
MongoClient preferredClient = mongo.getIfAvailable();
95+
if (preferredClient != null) {
96+
return new SimpleMongoDbFactory(preferredClient,
97+
this.properties.getMongoClientDatabase());
98+
}
99+
com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable();
100+
if (fallbackClient != null) {
101+
return new SimpleMongoClientDbFactory(fallbackClient,
102+
this.properties.getMongoClientDatabase());
103+
}
104+
throw new IllegalStateException("Expected to find at least one MongoDB client.");
103105
}
104106

105107
@Bean
@@ -183,87 +185,23 @@ public MongoDbFactory withSession(ClientSession session) {
183185
}
184186

185187
/**
186-
* Check if either {@link com.mongodb.MongoClient} or
187-
* {@link com.mongodb.client.MongoClient} is already defined in the
188-
* {@link org.springframework.context.ApplicationContext}.
189-
*
190-
* @author Christoph Strobl
191-
* @since 2.1
188+
* Check if either a {@link com.mongodb.MongoClient} or
189+
* {@link com.mongodb.client.MongoClient} bean is available.
192190
*/
193-
static class AnySyncMongoClientAvailable extends AnyNestedCondition {
191+
static class AnyMongoClientAvailable extends AnyNestedCondition {
194192

195-
AnySyncMongoClientAvailable() {
193+
AnyMongoClientAvailable() {
196194
super(ConfigurationPhase.REGISTER_BEAN);
197195
}
198196

199-
@ConditionalOnBean(com.mongodb.MongoClient.class)
200-
static class MongoClientPreferred {
197+
@ConditionalOnBean(MongoClient.class)
198+
static class PreferredClientAvailable {
201199

202200
}
203201

204202
@ConditionalOnBean(com.mongodb.client.MongoClient.class)
205-
static class MongoClientClientPreferred {
206-
207-
}
208-
209-
}
210-
211-
/**
212-
* Encapsulation of {@link MongoDbFactory} creation depending on available beans
213-
* {@link com.mongodb.MongoClient} or {@link com.mongodb.client.MongoClient} expressed
214-
* via the given {@link ObjectProvider ObjectProviders}. Prefers the first available
215-
* MongoDB client creating a suitable instance of {@link MongoDbFactory} for it.
216-
*
217-
* @author Christoph Strobl
218-
* @since 2.1
219-
*/
220-
static class MongoDbFactoryFactory {
221-
222-
private final List<ObjectProvider<?>> clientProviders;
223-
224-
/**
225-
* Create new instance of {@link MongoDbFactoryFactory}.
226-
* @param clientProviders order matters here, as we choose the first available
227-
* one.
228-
*/
229-
MongoDbFactoryFactory(ObjectProvider<?>... clientProviders) {
230-
this.clientProviders = Arrays.asList(clientProviders);
231-
}
232-
233-
/**
234-
* Get the {@link MongoDbFactory} suitable for the first available MongoDB client.
235-
* @param database the name of the default database to return on
236-
* {@link MongoDbFactory#getDb()}.
237-
* @return new instance of {@link MongoDbFactory} suitable for the first available
238-
* MongoDB client.
239-
*/
240-
MongoDbFactory getFor(String database) {
241-
242-
Object client = findAvailableClientProvider();
243-
244-
if (client instanceof MongoClient) {
245-
return new SimpleMongoDbFactory(MongoClient.class.cast(client), database);
246-
}
247-
248-
if (client instanceof com.mongodb.client.MongoClient) {
249-
return new SimpleMongoClientDbFactory(
250-
com.mongodb.client.MongoClient.class.cast(client), database);
251-
}
252-
253-
return null;
254-
}
255-
256-
private Object findAvailableClientProvider() {
257-
258-
for (ObjectProvider<?> provider : this.clientProviders) {
259-
Object client = provider.getIfAvailable();
260-
if (client != null) {
261-
return client;
262-
}
263-
}
203+
static class FallbackClientAvailable {
264204

265-
throw new IllegalStateException(
266-
"Expected to find at least one MongoDB client.");
267205
}
268206

269207
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.springframework.data.mongodb.MongoDbFactory;
4444
import org.springframework.data.mongodb.core.MongoTemplate;
4545
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;
46+
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
4647
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
4748
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
4849
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@@ -177,9 +178,16 @@ public void backsOffIfMongoClientBeanIsNotPresent() {
177178
}
178179

179180
@Test
180-
public void createsMongoDbFactoryForMongoClientClientWhenBeanPresent() {
181+
public void createsMongoDbFactoryForPreferredMongoClient() {
182+
this.contextRunner.run((context) -> {
183+
MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class);
184+
assertThat(dbFactory).isInstanceOf(SimpleMongoDbFactory.class);
185+
});
186+
}
181187

182-
this.contextRunner.withUserConfiguration(WithMongoClientClientConfiguration.class)
188+
@Test
189+
public void createsMongoDbFactoryForFallbackMongoClient() {
190+
this.contextRunner.withUserConfiguration(FallbackMongoClientConfiguration.class)
183191
.run((context) -> {
184192
MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class);
185193
assertThat(dbFactory).isInstanceOf(SimpleMongoClientDbFactory.class);
@@ -211,10 +219,10 @@ static class EntityScanConfig {
211219
}
212220

213221
@Configuration
214-
static class WithMongoClientClientConfiguration {
222+
static class FallbackMongoClientConfiguration {
215223

216224
@Bean
217-
com.mongodb.client.MongoClient mongoClient() {
225+
com.mongodb.client.MongoClient fallbackMongoClient() {
218226
return MongoClients.create();
219227
}
220228

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@
2323
import com.mongodb.client.MongoClients;
2424
import org.junit.Test;
2525

26-
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2726
import org.springframework.boot.autoconfigure.AutoConfigurations;
2827
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2928
import org.springframework.context.annotation.Bean;
3029
import org.springframework.context.annotation.Configuration;
3130

3231
import static org.assertj.core.api.Assertions.assertThat;
33-
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
3432
import static org.mockito.Mockito.mock;
3533

3634
/**
@@ -83,13 +81,13 @@ public void optionsSslConfig() {
8381

8482
@Test
8583
public void doesNotCreateMongoClientWhenAlreadyDefined() {
86-
8784
this.contextRunner
8885
.withPropertyValues("spring.data.mongodb.uri:mongodb://localhost/test")
89-
.withUserConfiguration(ConfigurationWithClientMongoClient.class)
90-
.run((context) -> assertThatExceptionOfType(
91-
NoSuchBeanDefinitionException.class)
92-
.isThrownBy(() -> context.getBean(MongoClient.class)));
86+
.withUserConfiguration(FallbackMongoClientConfig.class).run((context) -> {
87+
assertThat(context).doesNotHaveBean(MongoClient.class);
88+
assertThat(context)
89+
.hasSingleBean(com.mongodb.client.MongoClient.class);
90+
});
9391
}
9492

9593
@Configuration
@@ -118,10 +116,10 @@ public SocketFactory mySocketFactory() {
118116

119117
}
120118

121-
static class ConfigurationWithClientMongoClient {
119+
static class FallbackMongoClientConfig {
122120

123121
@Bean
124-
com.mongodb.client.MongoClient mongoClient() {
122+
com.mongodb.client.MongoClient fallbackMongoClient() {
125123
return MongoClients.create();
126124
}
127125

spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4029,6 +4029,10 @@ example, you might declare the following settings in your `application.propertie
40294029
spring.data.mongodb.port=27017
40304030
----
40314031

4032+
If you have defined your own `MongoClient`, it will be used to auto-configure a suitable
4033+
`MongoDbFactory`. Both `com.mongodb.MongoClient` and `com.mongodb.client.MongoClient`
4034+
are supported.
4035+
40324036
NOTE: If you use the Mongo 3.0 Java driver, `spring.data.mongodb.host` and
40334037
`spring.data.mongodb.port` are not supported. In such cases, `spring.data.mongodb.uri`
40344038
should be used to provide all of the configuration.

0 commit comments

Comments
 (0)