SpringBoot?整合mongoDB并自定義連接池的示例代碼
得力于SpringBoot的特性,整合mongoDB是很容易的,我們整合mongoDB的目的就是想用它給我們提供的mongoTemplate,它可以很容易的操作mongoDB數(shù)據(jù)庫。
為了自定義連接池,我們?cè)谂渲妙愔兄饕cMongoClientOptions、MongoCredential、MongoClient、MongoDbFactory打交道。最終的目的就是配置好一個(gè)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: [設(shè)置你的認(rèn)證數(shù)據(jù)庫,如果有的話]
# 連接池配置
clientName: ${spring.application.name} # 客戶端的標(biāo)識(shí),用于定位請(qǐng)求來源等
connectionTimeoutMs: 10000 # TCP連接超時(shí),毫秒
readTimeoutMs: 15000 # TCP讀取超時(shí),毫秒
poolMaxWaitTimeMs: 3000 #當(dāng)連接池?zé)o可用連接時(shí)客戶端阻塞等待的時(shí)長(zhǎng),單位毫秒
connectionMaxIdleTimeMs: 60000 #TCP連接閑置時(shí)間,單位毫秒
connectionMaxLifeTimeMs: 120000 #TCP連接最多可以使用多久,單位毫秒
heartbeatFrequencyMs: 20000 #心跳檢測(cè)發(fā)送頻率,單位毫秒
minHeartbeatFrequencyMs: 8000 #最小的心跳檢測(cè)發(fā)送頻率,單位毫秒
heartbeatConnectionTimeoutMs: 10000 #心跳檢測(cè)TCP連接超時(shí),單位毫秒
heartbeatReadTimeoutMs: 15000 #心跳檢測(cè)TCP連接讀取超時(shí),單位毫秒
connectionsPerHost: 20 # 每個(gè)host的TCP連接數(shù)
minConnectionsPerHost: 5 #每個(gè)host的最小TCP連接數(shù)
#計(jì)算允許多少個(gè)線程阻塞等待可用TCP連接時(shí)的乘數(shù),算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost,當(dāng)前配置允許10*20個(gè)線程阻塞
threadsAllowedToBlockForConnectionMultiplier: 10注意:其中的address參數(shù)可以配置為一個(gè)數(shù)組(代表集群模式)
address:
- "host:port"
- "host2:port2"MongoConfig配置類
配置類中使用了lombok,如果你沒有用lombok依賴和IDE插件,你要重寫getter、Setter方法:
代碼稍長(zhǎng),可以復(fù)制在IDEA中查看:
import com.mongodb.MongoClient;
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 {
/**
* monogo 轉(zhuǎn)換器
* @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));
mappingConverter.setCustomConversions(conversions);
return mappingConverter;
}
/**
* 自定義mongo連接池
* @param properties
* @return
*/
@Bean
public MongoDbFactory mongoDbFactory(MongoClientOptionProperties properties) {
//創(chuàng)建客戶端參數(shù)
MongoClientOptions options = mongoClientOptions(properties);
//創(chuàng)建客戶端和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);
}
//創(chuàng)建認(rèn)證客戶端
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)));
}
/** ps: 創(chuàng)建非認(rèn)證客戶端*/
//MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);
return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());
}
/**
* mongo客戶端參數(shù)配置
* @return
*/
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 {
/** 基礎(chǔ)連接參數(shù) */
private String database;
private String username;
private String password;
@NotNull
private List<String> address;
private String authenticationDatabase;
/** 客戶端連接池參數(shù) */
@NotNull
@Size(min = 1)
private String clientName;
/** socket連接超時(shí)時(shí)間 */
@Min(value = 1)
private int connectionTimeoutMs;
/** socket讀取超時(shí)時(shí)間 */
@Min(value = 1)
private int readTimeoutMs;
/** 連接池獲取鏈接等待時(shí)間 */
@Min(value = 1)
private int poolMaxWaitTimeMs;
/** 連接閑置時(shí)間 */
@Min(value = 1)
private int connectionMaxIdleTimeMs;
/** 連接最多可以使用多久 */
@Min(value = 1)
private int connectionMaxLifeTimeMs;
/** 心跳檢測(cè)發(fā)送頻率 */
@Min(value = 2000)
private int heartbeatFrequencyMs;
/** 最小的心跳檢測(cè)發(fā)送頻率 */
@Min(value = 300)
private int minHeartbeatFrequencyMs;
/** 計(jì)算允許多少個(gè)線程阻塞等待時(shí)的乘數(shù),算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost */
@Min(value = 1)
private int threadsAllowedToBlockForConnectionMultiplier;
/** 心跳檢測(cè)連接超時(shí)時(shí)間 */
@Min(value = 200)
private int heartbeatConnectionTimeoutMs;
/** 心跳檢測(cè)讀取超時(shí)時(shí)間 */
@Min(value = 200)
private int heartbeatReadTimeoutMs;
/** 每個(gè)host最大連接數(shù) */
@Min(value = 1)
private int connectionsPerHost;
/** 每個(gè)host的最小連接數(shù) */
@Min(value = 1)
private int minConnectionsPerHost;
}
}MappingMongoConverter可以自定義mongo轉(zhuǎn)換器,主要自定義存取mongo數(shù)據(jù)時(shí)的一些操作,例如 mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null)) 方法會(huì)將mongo數(shù)據(jù)中的_class字段去掉。
最后通過 new SimpleMongoDbFactory(mongoClient, properties.getDatabase())方法配置了一個(gè)MongoDbFactory交由Spring管理,Springboot會(huì)拿這個(gè)MongoDbFactory工廠bean來new一個(gè)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創(chuàng)建MongoTemplate實(shí)例
@Bean
@ConditionalOnMissingBean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) {
return new MongoTemplate(mongoDbFactory, converter);
@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在配置類中生成一個(gè)MongoTemplate,之后我們就可以在項(xiàng)目代碼中直接@Autowired了。因?yàn)橛糜谏蒑ongoTemplate的MongoDbFactory是我們自己在MongoConfig配置類中生成的,所以我們自定義的連接池參數(shù)也就生效了。
到此這篇關(guān)于SpringBoot 整合mongoDB并自定義連接池的文章就介紹到這了,更多相關(guān)SpringBoot自定義連接池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mongodb使用索引進(jìn)行查詢優(yōu)化的操作方法
為集合建立合適的索引,能夠有效的減少查詢操作時(shí)掃描數(shù)據(jù)的數(shù)量 ,從而提高查詢效率,簡(jiǎn)化了mongodb內(nèi)部查詢工作,這篇文章主要介紹了Mongodb使用索引進(jìn)行查詢優(yōu)化的操作方法,需要的朋友可以參考下2024-06-06
MongoDB進(jìn)階之動(dòng)態(tài)字段設(shè)計(jì)詳解
這篇文章主要給大家介紹了MongoDB進(jìn)階之動(dòng)態(tài)字段設(shè)計(jì)的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06
python實(shí)現(xiàn)爬蟲數(shù)據(jù)存到 MongoDB
本文給大家分享的是使用python實(shí)現(xiàn)將爬蟲爬到的數(shù)據(jù)存儲(chǔ)到mongoDB數(shù)據(jù)庫中的實(shí)例代碼,有需要的小伙伴可以參考下2016-09-09
教你使用MongoDB導(dǎo)入導(dǎo)出備份數(shù)據(jù)
這篇文章主要介紹了教你使用MongoDB導(dǎo)入導(dǎo)出備份數(shù)據(jù)方法的相關(guān)資料,需要的朋友可以參考下2022-11-11
mongodb數(shù)據(jù)庫的6個(gè)安全設(shè)置命令
這篇文章主要介紹了mongodb數(shù)據(jù)庫的6個(gè)安全設(shè)置命令,如安全模式啟動(dòng)、安全認(rèn)證、數(shù)據(jù)讀寫加鎖、解鎖等,需要的朋友可以參考下2014-05-05

