diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java index b04c1a895ec..ecc1b435c89 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,13 @@ package org.springframework.boot.autoconfigure.mongo; +import java.nio.channels.SocketChannel; import java.util.List; import javax.annotation.PreDestroy; import com.mongodb.async.client.MongoClientSettings; +import com.mongodb.connection.netty.NettyStreamFactoryFactory; import com.mongodb.reactivestreams.client.MongoClient; import org.springframework.beans.factory.ObjectProvider; @@ -30,6 +32,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; /** @@ -46,16 +50,10 @@ public class MongoReactiveAutoConfiguration { private final MongoClientSettings settings; - private final ReactiveMongoClientFactory factory; - private MongoClient mongo; - public MongoReactiveAutoConfiguration(MongoProperties properties, - ObjectProvider settings, Environment environment, - ObjectProvider> builderCustomizers) { + public MongoReactiveAutoConfiguration(ObjectProvider settings) { this.settings = settings.getIfAvailable(); - this.factory = new ReactiveMongoClientFactory(properties, environment, - builderCustomizers.getIfAvailable()); } @PreDestroy @@ -67,9 +65,35 @@ public class MongoReactiveAutoConfiguration { @Bean @ConditionalOnMissingBean - public MongoClient reactiveStreamsMongoClient() { - this.mongo = this.factory.createMongoClient(this.settings); + public MongoClient reactiveStreamsMongoClient(MongoProperties properties, + Environment environment, + ObjectProvider> builderCustomizers) { + ReactiveMongoClientFactory factory = new ReactiveMongoClientFactory(properties, + environment, builderCustomizers.getIfAvailable()); + this.mongo = factory.createMongoClient(this.settings); return this.mongo; } + @Configuration + @ConditionalOnClass(SocketChannel.class) + static class NettyDriverConfiguration { + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + public MongoClientSettingsBuilderCustomizer nettyDriverCustomizer( + ObjectProvider settings) { + return (builder) -> { + if (!isStreamFactoryFactoryDefined(settings.getIfAvailable())) { + builder.streamFactoryFactory( + NettyStreamFactoryFactory.builder().build()); + } + }; + } + + private boolean isStreamFactoryFactoryDefined(MongoClientSettings settings) { + return settings != null && settings.getStreamFactoryFactory() != null; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java index aadf0176395..2ff9ec3b1da 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,11 @@ import java.util.concurrent.TimeUnit; import com.mongodb.ReadPreference; import com.mongodb.async.client.MongoClientSettings; +import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory; import com.mongodb.connection.SocketSettings; import com.mongodb.connection.StreamFactory; import com.mongodb.connection.StreamFactoryFactory; +import com.mongodb.connection.netty.NettyStreamFactoryFactory; import com.mongodb.reactivestreams.client.MongoClient; import org.junit.Test; @@ -86,6 +88,16 @@ public class MongoReactiveAutoConfigurationTests { }); } + @Test + public void nettyStreamFactoryFactoryIsConfiguredAutomatically() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(MongoClient.class); + assertThat(context.getBean(MongoClient.class).getSettings() + .getStreamFactoryFactory()) + .isInstanceOf(NettyStreamFactoryFactory.class); + }); + } + @Test public void customizerOverridesAutoConfig() { this.contextRunner @@ -95,6 +107,8 @@ public class MongoReactiveAutoConfigurationTests { MongoClient client = context.getBean(MongoClient.class); assertThat(client.getSettings().getApplicationName()) .isEqualTo("overridden-name"); + assertThat(client.getSettings().getStreamFactoryFactory()) + .isEqualTo(SimpleCustomizerConfig.streamFactoryFactory); }); } @@ -133,10 +147,14 @@ public class MongoReactiveAutoConfigurationTests { @Configuration static class SimpleCustomizerConfig { + private static final StreamFactoryFactory streamFactoryFactory = + new AsynchronousSocketChannelStreamFactoryFactory(); + @Bean public MongoClientSettingsBuilderCustomizer customizer() { return (clientSettingsBuilder) -> clientSettingsBuilder - .applicationName("overridden-name"); + .applicationName("overridden-name") + .streamFactoryFactory(streamFactoryFactory); } } 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 bffe50b2056..270262dcf49 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 @@ -3660,7 +3660,9 @@ instead of using `MongoDbFactory`. If you want to take complete control of estab the MongoDB connection, you can also declare your own `MongoDbFactory` or `MongoClient` bean. - +NOTE: If you are using the reactive driver, Netty is required for SSL. The +auto-configuration configures this factory automatically if Netty is available and the +factory to use hasn't been customized already. [[boot-features-mongo-template]] ==== MongoTemplate