001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.mongo; 018 019import java.util.stream.Collectors; 020 021import javax.annotation.PreDestroy; 022 023import com.mongodb.MongoClientSettings; 024import com.mongodb.connection.netty.NettyStreamFactoryFactory; 025import com.mongodb.reactivestreams.client.MongoClient; 026import io.netty.channel.socket.SocketChannel; 027import reactor.core.publisher.Flux; 028 029import org.springframework.beans.factory.ObjectProvider; 030import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 031import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 032import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 033import org.springframework.boot.context.properties.EnableConfigurationProperties; 034import org.springframework.context.annotation.Bean; 035import org.springframework.context.annotation.Configuration; 036import org.springframework.core.Ordered; 037import org.springframework.core.annotation.Order; 038import org.springframework.core.env.Environment; 039 040/** 041 * {@link EnableAutoConfiguration Auto-configuration} for Reactive Mongo. 042 * 043 * @author Mark Paluch 044 * @author Stephane Nicoll 045 * @since 2.0.0 046 */ 047@Configuration 048@ConditionalOnClass({ MongoClient.class, Flux.class }) 049@EnableConfigurationProperties(MongoProperties.class) 050public class MongoReactiveAutoConfiguration { 051 052 private final MongoClientSettings settings; 053 054 private MongoClient mongo; 055 056 public MongoReactiveAutoConfiguration(ObjectProvider<MongoClientSettings> settings) { 057 this.settings = settings.getIfAvailable(); 058 } 059 060 @PreDestroy 061 public void close() { 062 if (this.mongo != null) { 063 this.mongo.close(); 064 } 065 } 066 067 @Bean 068 @ConditionalOnMissingBean 069 public MongoClient reactiveStreamsMongoClient(MongoProperties properties, 070 Environment environment, 071 ObjectProvider<MongoClientSettingsBuilderCustomizer> builderCustomizers) { 072 ReactiveMongoClientFactory factory = new ReactiveMongoClientFactory(properties, 073 environment, 074 builderCustomizers.orderedStream().collect(Collectors.toList())); 075 this.mongo = factory.createMongoClient(this.settings); 076 return this.mongo; 077 } 078 079 @Configuration 080 @ConditionalOnClass(SocketChannel.class) 081 static class NettyDriverConfiguration { 082 083 @Bean 084 @Order(Ordered.HIGHEST_PRECEDENCE) 085 public MongoClientSettingsBuilderCustomizer nettyDriverCustomizer( 086 ObjectProvider<MongoClientSettings> settings) { 087 return (builder) -> { 088 if (!isStreamFactoryFactoryDefined(settings.getIfAvailable())) { 089 builder.streamFactoryFactory( 090 NettyStreamFactoryFactory.builder().build()); 091 } 092 }; 093 } 094 095 private boolean isStreamFactoryFactoryDefined(MongoClientSettings settings) { 096 return settings != null && settings.getStreamFactoryFactory() != null; 097 } 098 099 } 100 101}