MongoDB7.0--SpringBoot配置mongodb连接池
摘要
-
本文介绍如何使用SpringBoot配置MongoDB7.0的连接池
-
SpringBoot版本3.2.4,MongoDB版本7.0.6
-
关于springboot与mongodb的集成可以参考:MongoDB7.0--SpringBoot单集合操作,本文只讨论连接池相关内容。
spring-boot 的 MongoDB 连接池
-
当我们在springboot的配置文件中配置mongodb的相关属性时,并没有发现和连接池相关的属性,查看
MongoProperties
中的属性也可以证实这一点,这就很奇怪,按理说springboot应该不会这么弱鸡。 -
于是我打算看看springboot的源码,看看springboot为我们自动创建的
MongoClient
到底有没有连接池的配置。 -
我们就从mongodb的自动配置类
MongoAutoConfiguration
开始,该类中定义了PropertiesMongoConnectionDetails
和MongoClient
1 | //这个类主要用于ConnectionString对象的封装,后面会讲到 |
-
可以看到,创建
MongoClient
的bean时,依赖两个参数,一个是ObjectProvider<MongoClientSettingsBuilderCustomizer>
,一个是MongoClientSettings
,前者会将spring上下文中所有类型为MongoClientSettingsBuilderCustomizer
的bean封装到该对象中(springboot默认只提供了一个StandardMongoClientSettingsBuilderCustomizer
) -
MongoAutoConfiguration
缺省为我们提供了MongoClientSettings
和StandardMongoClientSettingsBuilderCustomizer
,这两个类都很重要,连接池参数就和它们有关
1 |
|
-
我们先看
MongoClientSettings
,其中就定义一个连接池的配置对象ConnectionPoolSettings
,而ConnectionPoolSettings
其内部就定义了连接池的配置属性,MongoClientSettings
通过ConnectionPoolSettings
的构造器创建出了ConnectionPoolSettings
对象,其缺省值如下:
1 | private int maxSize = 100; |
-
我们看另一个和创建
MongoClient
相关的bean,这个StandardMongoClientSettingsBuilderCustomizer
,创建这个bean时需要一个MongoConnectionDetails
对象,并调用其getConnectionString
方法,这个对象MongoAutoConfiguration
也为我们提供了(上面可以看到) -
查看
PropertiesMongoConnectionDetails
的源码,发现connectionDetails.getConnectionString()
的功能就是将MongoProperties
的属性封装为uri
并传递给ConnectionString
的构造器创建对象
1 | public ConnectionString getConnectionString() { |
-
这个
ConnectionString
对象的初始化过程就很有意思了,其会对这个uri
进行解析,解析过程中会调用parseOptions(connectionStringQueryParameters)
方法,其会将uri
中的参数转换为Map
,之后调用translateOptions(combinedOptionsMaps)
方法遍历这个map,而在遍历的过程中就会完成对ConnectionString
对象的连接池相关属性的初始化
1 | private void translateOptions(final Map<String, List<String>> optionsMap) { |
-
其实此时我们就已经知道应该如何配置连接池参数了,就是将连接池相关的参数追加到
uri
的参数部分,但是前面我们提到负责连接池的类是ConnectionPoolSettings
,那么ConnectionString
对象中的连接池属性是如何被传递给ConnectionPoolSettings
的呢,我们接着往下看。 -
参数准备好后就开始创建
MongoClient
了,其会调用MongoClientFactory
的createMongoClient
方法,其会对MongoClientSettings
对象做进一步的封装,并最终基于封装后的MongoClientSettings
对象创建出MongoClient
对象
1 | public T createMongoClient(MongoClientSettings settings) { |
-
而在进一步封装
MongoClientSettings
对象时,会调用系统中所有被spring管理的MongoClientSettingsBuilderCustomizer
,实际上也就是StandardMongoClientSettingsBuilderCustomizer
的customize
方法,其又会调用MongoClientSettings.builder()
的applyConnectionSettings
方法,而在该方法中调用connectionPoolSettingsBuilder.applyConnectionString(connectionString);
就完成了将ConnectionString
对象中的连接池属性传递给ConnectionPoolSettings
对象的过程,当然,如果属性没有获取到就会使用默认值,所以我们可以基于需要配置相关的属性。
1 | public Builder applyConnectionString(final ConnectionString connectionString) { |
-
大体过程就是这样,很绕,简单点说就是springboot已经为我们提供了mongodb的连接池,我们也可以基于需要,在配置
mongodb-uri
时,增加相关的连接池参数,springboot就会按照我们配置的参数为我们创建连接池,并自动管理连接池。
1 | spring: |
-
参数说明
1 | maxpoolsize: 100 # 池中允许的最大连接数。一旦池耗尽,任何需要连接的操作都将在阻塞队列中等待直到获取到连接, 默认: 100 |
如何查看连接池是否生效了?
-
很简单,我们只需要注入
MongoClient
并查看其settings
属性,就可以看到连接池的配置信息了`
1 |
|
后记
-
springboot为什么没有将mongodb的连接池属性也封装到
MongoProperties
中呢,也许是因为和mongodb相关的链接参数太多了吧,而且我们在配置mongodb时,一般都会使用mongodb-uri
的方式,所以springboot就直接将连接池参数放到mongodb-uri
中,这样配置起来就比较方便了。 -
另外我们发现,在
MongoClientSettings
中除了连接池的配置,还有很多配置项也是基于mongodb-uri
的,我们可以基于需要进行配置,如下所示:
1 | private final ReadPreference readPreference; |