import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Configuration
@EnableConfigurationProperties(MongoConfig.MongoClientOptionProperties.class)
public class MongoConfig {
@Bean
public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory,
MongoMappingContext context, BeanFactory beanFactory, MongoCustomConversions conversions) {
DbRefResolver dbRefResolver=new DefaultDbRefResolver(factory);
MappingMongoConverter mappingConverter=new MappingMongoConverter(dbRefResolver, context);
// remove _class field
// mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
mappingConverter.setCustomConversions(conversions);
return mappingConverter;
}
@Bean
public MongoDbFactory mongoDbFactory(MongoClientOptionProperties properties) {
//创建客户端参数
MongoClientOptions options=mongoClientOptions(properties);
//创建客户端和Factory
List<ServerAddress> serverAddresses=new ArrayList<>();
for (String address : properties.getAddress()) {
String[] hostAndPort=address.split(“:”);
String host=hostAndPort[0];
Integer port=Integer.parseInt(hostAndPort[1]);
ServerAddress serverAddress=new ServerAddress(host, port);
serverAddresses.add(serverAddress);
}
//创建认证客户端
MongoCredential mongoCredential=MongoCredential.createScramSha1Credential(properties.getUsername(),
properties.getAuthenticationDatabase() !=null ? properties.getAuthenticationDatabase() : properties.getDatabase(),
properties.getPassword().toCharArray());
MongoClient mongoClient=new MongoClient(serverAddresses.get(0), mongoCredential, options);
//集群模式
if (serverAddresses.size() > 1) {
mongoClient=new MongoClient(serverAddresses, new ArrayList<>(Arrays.asList(mongoCredential)));
}
//MongoClient mongoClient=new MongoClient(serverAddresses, mongoClientOptions);
return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());
}
public MongoClientOptions mongoClientOptions(MongoClientOptionProperties properties) {
return MongoClientOptions.builder()
.connectTimeout(properties.getConnectionTimeoutMs())
.socketTimeout(properties.getReadTimeoutMs()).applicationName(properties.getClientName())
.heartbeatConnectTimeout(properties.getHeartbeatConnectionTimeoutMs())
.heartbeatSocketTimeout(properties.getHeartbeatReadTimeoutMs())
.heartbeatFrequency(properties.getHeartbeatFrequencyMs())
.minHeartbeatFrequency(properties.getMinHeartbeatFrequencyMs())
.maxConnectionIdleTime(properties.getConnectionMaxIdleTimeMs())
.maxConnectionLifeTime(properties.getConnectionMaxLifeTimeMs())
.maxWaitTime(properties.getPoolMaxWaitTimeMs())
.connectionsPerHost(properties.getConnectionsPerHost())
.threadsAllowedToBlockForConnectionMultiplier(
properties.getThreadsAllowedToBlockForConnectionMultiplier())
.minConnectionsPerHost(properties.getMinConnectionsPerHost()).build();
}
@Getter
@Setter
@Validated
@ConfigurationProperties(prefix=”mongodb”)
public static class MongoClientOptionProperties {
private String database;
private String username;
private String password;
@NotNull
private List<String> address;
private String authenticationDatabase;
@NotNull
@Size(min=1)
private String clientName;
@Min(value=1)
private int connectionTimeoutMs;
@Min(value=1)
private int readTimeoutMs;
@Min(value=1)
private int poolMaxWaitTimeMs;
@Min(value=1)
private int connectionMaxIdleTimeMs;
@Min(value=1)
private int connectionMaxLifeTimeMs;
@Min(value=2000)
private int heartbeatFrequencyMs;
@Min(value=300)
private int minHeartbeatFrequencyMs;
@Min(value=1)
private int threadsAllowedToBlockForConnectionMultiplier;
@Min(value=200)
private int heartbeatConnectionTimeoutMs;
@Min(value=200)
private int heartbeatReadTimeoutMs;
@Min(value=1)
private int connectionsPerHost;
@Min(value=1)
private int minConnectionsPerHost;
}
}