Spring Boot + MongoDB:如何复用数据库连接
Spring Boot + MongoDB 连接池配置与连接复用规范
你现在遇到的问题其实是踩了MongoDB客户端使用的一个常见坑——每次调用docStoreConfig.mongoClient()都新建了MongoClient实例!要知道,MongoClient是线程安全的重量级对象,它本身就内置了连接池机制,频繁创建销毁不仅会严重拖慢性能,还会快速耗尽数据库的连接资源。下面给你讲清楚正确的规范和实现方式:
一、先修复你现有代码的连接复用问题
如果坚持用自定义的DocumentStoreConfig,核心要保证mongoClient()方法返回的是单例实例,让Spring帮你管理这个对象的生命周期:
- 确保你的
DocumentStoreConfig是配置类,用@Configuration标记 - 给
mongoClient()方法加上@Bean注解,这样Spring只会创建一次这个实例,每次注入或调用都是同一个对象 - 在方法内部配置连接池参数,示例代码如下:
@Configuration public class DocumentStoreConfig { @Bean public MongoClient mongoClient() { // 构建连接池配置 ConnectionPoolSettings poolSettings = ConnectionPoolSettings.builder() .maxSize(100) // 连接池最大连接数,根据并发量调整 .minSize(10) // 最小空闲连接数,维持基础连接池大小 .maxConnectionIdleTime(Duration.ofSeconds(30)) // 连接最大空闲时间,超时回收 .maxConnectionLifeTime(Duration.ofSeconds(60)) // 连接最大存活时间,避免长期占用 .maxWaitTime(Duration.ofSeconds(10)) // 获取连接的最大等待时间,防止线程阻塞 .build(); // 构建MongoClient配置 MongoClientSettings clientSettings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString("mongodb://localhost:27017")) .applyConnectionPoolSettings(poolSettings) .build(); return MongoClients.create(clientSettings); } }
这样之后,你通过@Autowired注入DocumentStoreConfig后,每次调用mongoClient()拿到的都是同一个单例,连接池也会正常工作。
二、更推荐:使用Spring Boot MongoDB Starter的标准配置
其实Spring Boot官方已经为MongoDB整合做了非常完善的自动配置,完全不需要手动写配置类,直接用spring-boot-starter-data-mongodb依赖即可:
- 先在pom.xml(或build.gradle)中引入依赖:
<!-- Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
- 在
application.yml(或application.properties)中配置连接和连接池参数:
spring: data: mongodb: uri: mongodb://localhost:27017/your_db_name connection-pool: max-size: 100 min-size: 10 max-connection-idle-time: 30s max-connection-life-time: 60s max-wait-time: 10s
- 然后在业务代码中直接注入
MongoClient或者更易用的MongoTemplate即可,Spring已经帮你做好了单例管理和连接池配置:
@Service public class YourDocumentService { // 直接注入单例的MongoClient @Autowired private MongoClient mongoClient; // 或者更推荐用MongoTemplate,它封装了更多CRUD操作的便捷方法 @Autowired private MongoTemplate mongoTemplate; public void saveDocument(Object doc, String collectionName) { // 用MongoClient的方式,复用单例连接池 mongoClient.getDatabase("your_db_name").getCollection(collectionName).insertOne(doc); // 用MongoTemplate的方式更简洁,无需手动指定数据库和集合 mongoTemplate.insert(doc, collectionName); } }
三、核心规范要点
- 必须复用MongoClient实例:一个应用(针对同一个MongoDB集群)只需要一个
MongoClient单例,它是线程安全的,所有线程共享这个实例的连接池。 - 合理配置连接池参数:根据应用的并发请求量调整
max-size,不要设置过大(比如超过数据库允许的最大连接数);通过maxConnectionIdleTime和maxConnectionLifeTime回收闲置连接,避免资源浪费。 - 优先用官方自动配置:Spring Boot的MongoDB Starter已经实现了最佳实践,手动配置容易出错,除非你有特殊的自定义需求(比如连接多个集群)。
- 禁止在业务代码中新建MongoClient:永远不要在Service/Controller的方法里每次调用都创建
MongoClient,这是性能杀手。
内容的提问来源于stack exchange,提问作者Navdeep Shergill
相关产品推荐
相关产品推荐

