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
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并自定义连接池的更多相关文章
- (二)SpringBoot整合常用框架Druid连接池
一,在Pom.xml文件加入依赖 找到<dependencies></dependencies>标签,在标签中添加Druid依赖 <dependency> < ...
- java操作mongodb & springboot整合mongodb
简单的研究原生API操作MongoDB以及封装的工具类操作,最后也会研究整合spring之后作为dao层的完整的操作. 1.原生的API操作 pom.xml <!-- https://mvnre ...
- SpringBoot 整合 MongoDB 实战介绍
一.介绍 在前面的文章中,我们详细的介绍了 MongoDB 的配置和使用,如果你对 MongoDB 还不是很了解,也没关系,在 MongoDB 中有三个比较重要的名词:数据库.集合.文档! 数据库(D ...
- Springboot整合MongoDB的Docker开发,其它应用也类似
1 前言 Docker是容器开发的事实标准,而Springboot是Java微服务常用框架,二者必然是会走到一起的.本文将讲解如何开发Springboot项目,把它做成Docker镜像,并运行起来. ...
- Springboot 整合 MongoDB
Springboot 整合 MongoDB 这节我们将整合 Spring Boot 与 Mongo DB 实现增删改查的功能,并且实现序列递增. Mongo DB 的基本介绍和增删改查的用法可以参考我 ...
- mongoDB中的连接池(转载)
一.mongoDB中的连接池 刚上手MongoDB,在做应用时,受以前使用关系型数据库的影响,会考虑数据库连接池的问题! 关系型数据库中,我们做连接池无非就是事先建立好N个连接(connection) ...
- JDBC连接池-自定义连接池
JDBC连接池 java JDBC连接中用到Connection 在每次对数据进行增删查改 都要 开启 .关闭 ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例 pack ...
- java自定义连接池
1.java自定义连接池 1.1连接池的概念: 实际开发中"获取连接"或“释放资源”是非常消耗系统资源的两个过程,为了姐姐此类性能问题,通常情况我们采用连接池技术来贡献连接Conn ...
- SpringBoot整合mongoDB
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 这一片文章介绍一个springboot整合mongodb,如果你了解整合mysql之类的 ...
随机推荐
- MATLAB实例:聚类初始化方法与数据归一化方法
MATLAB实例:聚类初始化方法与数据归一化方法 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 聚类初始化方法:init_methods.m f ...
- 学习笔记12JS异步请求
*一般用JS来监听按钮事件,都应该先监听页面OnLoad事件. *Js写在哪里,就会在页面解析到哪里执行. 异步请求:所谓异步请求,就是使用JS来监听按钮点击事件,并且发送请求,等到回复后,再使用JS ...
- shell 字符串比较与脚本 too many arguments 报错
一.问题 最近在写 shell 脚本的时候,遇到了一些小问题,就是我在判断一个字符串是否为空的时候经常报下面的错,程序是正常执行了,但是有这个提示很蛋疼,下面就是看看是什么问题导致的? [: too ...
- 使用Typescript重构axios(八)——实现基础功能:处理响应data
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用vue-cookies操作cookie
1.前言 在vue中如果想要操作cookie,除了使用之前我们自己封装好的操作cookie的方法之外,我们还可以使用vue-cookies插件,这是一个简单的Vue.js插件,专门用于在vue中处理浏 ...
- 【倒腾HTTPS】Nginx for Docker自签名SSL证书
前言 合格的web程序员, 必须能自由在 IIS. Nginx. Nginx for Docker上配置Https服务, 博客最近将专题记录 Https & Hsts 如何申请适用于生产 ...
- 你了解MySQL的加锁规则吗?
注:加锁规则指的是next-key lock,如果还不了解next-key lock,请阅读上一篇博客 加锁规则可以概括为:两个原则.两个优化和一个bug: 原则1:加锁的基本单位是next-key ...
- ios遇到的坑
总结体会:很多ios兼容性问题都是由于body设置了height:100% ios中input输入不了 在ios中margin属性不起作用 设置html body的高度为百分比时,margin-bot ...
- CSS如何修改tr边框属性
有很多时候,我们都要自定义为表格合并边框,这个只要 table{ border-collapse:collapse; } 就可以了 参数: separate 默认值.边框会被分开.不会忽略border ...
- IDEA+JSP+Servlet+Tomcat简单的登录示例
1.用IDEA新建Java WEB项目并配置Tomcat 这一部分可以参考之前的一篇随笔 https://www.cnblogs.com/lbhym/p/11496610.html 2.导入Servl ...