SpringBoot整合mongoDB并⾃定义连接池
SpringBoot 整合mongoDB并⾃定义连接池
得⼒于SpringBoot的特性,整合mongoDB是很容易的,我们整合mongoDB的⽬的就是想⽤它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数据库。
为了⾃定义连接池,我们在配置类中主要与MongoClientOptions、MongoCredential、MongoClient、MongoDbFactory打交道。最终的⽬的就是配置好⼀个MongoDbFactory的bean交由Spring管理。
Maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置⽂件
mongodb:
database: bfa_mongo
username: "xxx"
password: "xxxxx"
address: "host:port"
authenticationDatabase: [设置你的认证数据库,如果有的话]
# 连接池配置
clientName: ${spring.application.name} # 客户端的标识,⽤于定位请求来源等
connectionTimeoutMs: 10000 # TCP连接超时,毫秒
readTimeoutMs: 15000 # TCP读取超时,毫秒
poolMaxWaitTimeMs: 3000 #当连接池⽆可⽤连接时客户端阻塞等待的时长,单位毫秒
connectionMaxIdleTimeMs: 60000 #TCP连接闲置时间,单位毫秒
connectionMaxLifeTimeMs: 120000 #TCP连接最多可以使⽤多久,单位毫秒
heartbeatFrequencyMs: 20000 #⼼跳检测发送频率,单位毫秒
minHeartbeatFrequencyMs: 8000 #最⼩的⼼跳检测发送频率,单位毫秒
heartbeatConnectionTimeoutMs: 10000 #⼼跳检测TCP连接超时,单位毫秒
heartbeatReadTimeoutMs: 15000 #⼼跳检测TCP连接读取超时,单位毫秒
connectionsPerHost: 20 # 每个host的TCP连接数
minConnectionsPerHost: 5 #每个host的最⼩TCP连接数
#计算允许多少个线程阻塞等待可⽤TCP连接时的乘数,算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost,当前配置允许10*20个线程阻塞
threadsAllowedToBlockForConnectionMultiplier: 10
注意:其中的address参数可以配置为⼀个数组(代表集模式)
address:
- "host:port"
- "host2:port2"
MongoConfig配置类
配置类中使⽤了lombok,如果你没有⽤lombok依赖和IDE插件,你要重写getter、Setter⽅法:
代码稍长,可以复制在IDEA中查看:
db.MongoClient;
db.MongoClientOptions;
db.MongoCredential;
db.ServerAddress;
import lombok.Getter;
import lombok.Setter;
slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.t.properties.ConfigurationProperties;
import org.t.properties.EnableConfigurationProperties;
import t.annotation.Bean;
import t.annotation.Configuration;
import t.annotation.Primary;
import org.db.MongoDbFactory;
import org.db.core.SimpleMongoDbFactory;
import org.vert.DbRefResolver;
import org.vert.DefaultDbRefResolver;
import org.vert.MappingMongoConverter;
import org.vert.MongoCustomConversions;
import org.db.core.mapping.MongoMappingContext;
import org.springframework.validation.annotation.Validated;
import straints.Min;
import straints.NotNull;
import straints.Size;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Configuration
@EnableConfigurationProperties(MongoConfig.MongoClientOptionProperties.class)
public class MongoConfig {
/**
* monogo 转换器
* @return
*/
@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));spring怎么读取properties
mappingConverter.setCustomConversions(conversions);
return mappingConverter;
}
/**
* ⾃定义mongo连接池
* @param properties
* @return
*/
@Bean
public MongoDbFactory mongoDbFactory(MongoClientOptionProperties properties) {
//创建客户端参数
MongoClientOptions options = mongoClientOptions(properties);
//创建客户端和Factory
List<ServerAddress> serverAddresses = new ArrayList<>();
for (String address : Address()) {
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 = Username(),
MongoClient mongoClient = new (0), mongoCredential, options);
//集模式
if (serverAddresses.size() > 1) {
mongoClient = new MongoClient(serverAddresses, new ArrayList<>(Arrays.asList(mongoCredential)));
}
/** ps: 创建⾮认证客户端*/
//MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);
return new SimpleMongoDbFactory(mongoClient, Database());
}
/**
* mongo客户端参数配置
* @return
*/
public MongoClientOptions mongoClientOptions(MongoClientOptionProperties properties) {
return MongoClientOptions.builder()
.
ConnectionTimeoutMs())
.ReadTimeoutMs()).ClientName())
.HeartbeatConnectionTimeoutMs())
.HeartbeatReadTimeoutMs())
.HeartbeatFrequencyMs())
.MinHeartbeatFrequencyMs())
.ConnectionMaxIdleTimeMs())
.ConnectionMaxLifeTimeMs())
.PoolMaxWaitTimeMs())
.ConnectionsPerHost())
.threadsAllowedToBlockForConnectionMultiplier(
.MinConnectionsPerHost()).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;
/** socket连接超时时间 */
@Min(value = 1)
private int connectionTimeoutMs;
/
** socket读取超时时间 */
@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;
/** 计算允许多少个线程阻塞等待时的乘数,算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost */
@Min(value = 1)
private int threadsAllowedToBlockForConnectionMultiplier;
/** ⼼跳检测连接超时时间 */
@Min(value = 200)
private int heartbeatConnectionTimeoutMs;
/** ⼼跳检测读取超时时间 */
@Min(value = 200)
private int heartbeatReadTimeoutMs;
/** 每个host最⼤连接数 */
@Min(value = 1)
private int connectionsPerHost;
/** 每个host的最⼩连接数 */
@Min(value = 1)
private int minConnectionsPerHost;
}
}
MappingMongoConverter可以⾃定义mongo转换器,主要⾃定义存取mongo数据时的⼀些操作,例如 mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null)) ⽅法会将mongo数据中的_class字段去掉。
最后通过 new SimpleMongoDbFactory(mongoClient, Database())⽅法配置了⼀个MongoDbFactory交由Spring管理,Springboot会拿这个MongoDbFactory⼯⼚bean来new⼀个MongoTemplate,在MongoDbFactoryDependentConfiguration类下可以看到SpringBoot帮你做得事:
/**
* Configuration for Mongo-related beans that depend on a {@link MongoDbFactory}.
*
* @author Andy Wilkinson
*/
@Configuration
@ConditionalOnBean(MongoDbFactory.class)
class MongoDbFactoryDependentConfiguration {
private final MongoProperties properties;
MongoDbFactoryDependentConfiguration(MongoProperties properties) {
this.properties = properties;
}
//SpringBoot创建MongoTemplate实例
@Bean
@ConditionalOnMissingBean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) {
return new MongoTemplate(mongoDbFactory, converter);
}
@Bean
@ConditionalOnMissingBean(MongoConverter.class)
public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context,
MongoCustomConversions conversions) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
mappingConverter.setCustomConversions(conversions);
return mappingConverter;
}
//...
}
SpringBoot利⽤我们配置好的MongoDbFactory在配置类中⽣成⼀个MongoTemplate,之后我们就可以在项⽬代码中直接@Autowired了。因为⽤于⽣成MongoTemplate的MongoDbFactory是我们⾃⼰在MongoConfig配置类中⽣成的,所以我们⾃定义的连接池参数也就⽣效了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论