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

MongoConfig配置类

配置类中使用了lombok,如果你没有用lombok依赖和IDE插件,你要重写getter、Setter方法:

代码稍长,可以复制在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.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.List; @Slf4j
@Configuration
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);
// 删除 _class field
// mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
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 : 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, mongoCredential, options); /** ps: 创建非认证客户端*/
//MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);
return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());
} /**
* mongo客户端参数配置
* @return
*/
@Bean
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();
} @Primary
@Bean
@ConfigurationProperties(prefix = "mongodb")
public MongoClientOptionProperties mongoClientOptionProperties() {
return new MongoClientOptionProperties();
} @Getter
@Setter
@Validated
@Configuration
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, properties.getDatabase())方法配置了一个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配置类中生成的,所以我们自定义的连接池参数也就生效了。

SpringBoot 整合mongoDB并自定义连接池的更多相关文章

  1. (二)SpringBoot整合常用框架Druid连接池

    一,在Pom.xml文件加入依赖 找到<dependencies></dependencies>标签,在标签中添加Druid依赖 <dependency> < ...

  2. java操作mongodb & springboot整合mongodb

    简单的研究原生API操作MongoDB以及封装的工具类操作,最后也会研究整合spring之后作为dao层的完整的操作. 1.原生的API操作 pom.xml <!-- https://mvnre ...

  3. SpringBoot 整合 MongoDB 实战介绍

    一.介绍 在前面的文章中,我们详细的介绍了 MongoDB 的配置和使用,如果你对 MongoDB 还不是很了解,也没关系,在 MongoDB 中有三个比较重要的名词:数据库.集合.文档! 数据库(D ...

  4. Springboot整合MongoDB的Docker开发,其它应用也类似

    1 前言 Docker是容器开发的事实标准,而Springboot是Java微服务常用框架,二者必然是会走到一起的.本文将讲解如何开发Springboot项目,把它做成Docker镜像,并运行起来. ...

  5. Springboot 整合 MongoDB

    Springboot 整合 MongoDB 这节我们将整合 Spring Boot 与 Mongo DB 实现增删改查的功能,并且实现序列递增. Mongo DB 的基本介绍和增删改查的用法可以参考我 ...

  6. mongoDB中的连接池(转载)

    一.mongoDB中的连接池 刚上手MongoDB,在做应用时,受以前使用关系型数据库的影响,会考虑数据库连接池的问题! 关系型数据库中,我们做连接池无非就是事先建立好N个连接(connection) ...

  7. JDBC连接池-自定义连接池

    JDBC连接池 java JDBC连接中用到Connection   在每次对数据进行增删查改 都要 开启  .关闭  ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例 pack ...

  8. java自定义连接池

    1.java自定义连接池 1.1连接池的概念: 实际开发中"获取连接"或“释放资源”是非常消耗系统资源的两个过程,为了姐姐此类性能问题,通常情况我们采用连接池技术来贡献连接Conn ...

  9. SpringBoot整合mongoDB

    MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 这一片文章介绍一个springboot整合mongodb,如果你了解整合mysql之类的 ...

随机推荐

  1. 高频Linux命令小结(新手向)

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 近期 ...

  2. 虚拟机kali linux与windows主机共享文件

    在windows中我们可以直接拖拽文件,有的时候wmtools无效 很苦恼 从kali中托文件就不可以, 于是那就用到了共享文件夹 一.在虚拟机名称处右键,选择设置,会弹出一个设置框 二.选择选项-& ...

  3. csps模拟测试 77爆零反思

    题不算太难,可是我还是没考出应有水平. $1h8min$切掉前两道题,然后$T3$想到正解并且码出来了并且过了大样例并且爆零. 没什么好说的,我太自信了,没打对拍? 想到了正解,还不如随便打个暴力分高 ...

  4. 如何在Vue-cli项目中使用JTopo

    1.前言 jTopo(Javascript Topology library)是一款完全基于HTML5 Canvas的关系.拓扑图形化界面开发工具包.其体积小,性能优异,由一群开发爱好者来维护.唯一感 ...

  5. 如何在vue-cli项目中结合mockjs模拟假数据

    1.前言 在如今前后端分离的开发方式已被广泛采用的今天,前端同学和后端同学各自独立开发,后端提供数据接口,前端调用接口获取数据渲染页面.但是在实际开发中,后端开发由于逻辑相对复杂接口迟迟提供不到位,而 ...

  6. 『题解』POJ1753 Flip Game

    题目传送门 题意描述 有\(4 \times 4\)的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑\(\to\)白 或 白\(\to\)黑)时,其周围上下左右(如果存在的话)的格 ...

  7. 手写Spring框架,加深对Spring工作机制的理解!

    在我们的日常工作中,经常会用到Spring.Spring Boot.Spring Cloud.Struts.Mybatis.Hibernate等开源框架,有了这些框架的诞生,平时的开发工作量也是变得越 ...

  8. Kubernetes 挂载文件到pod里面

    下面以chart为例子: 1.创建ConfigMap,这里要注意config.js为挂载的文件名 [root@cn-hongkong templates]# cat app-config.yaml a ...

  9. Unity中用Mesh画一个圆环

    Probuider 前几天在做一个小项目的时候,用到了Unity自带的一个包ProBuilder其中的Arch生成1/4圆. 挺好玩的,可以在直接Unity中根据需要用Mesh定制生成图形,而不用建模 ...

  10. powerdesigner连接Mysql进行反向工程并生成word文档图文教程

    1 软件版本 windows7 64位 powerdesigner 15.1 Mysql 5.1.56 mysql-connector-odbc-3.51.30-winx64 对于mysql-conn ...