得力于SpringBoot的特性,整合mongoDB是很容易的,我們整合mongoDB的目的就是想用它給我們提供的mongoTemplate,它可以很容易的操作mongoDB數據庫。
為了自定義連接池,我們在配置類中主要與MongoClientOptions、MongoCredential、MongoClient、MongoDbFactory打交道。最終的目的就是配置好一個MongoDbFactory的bean交由Spring管理。
Maven 依賴
1
2
3
4
|
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> |
配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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 |
注意:其中的address參數可以配置為一個數組(代表集群模式)
1
2
3
|
address: - "host:port" - "host2:port2" |
MongoConfig配置類
配置類中使用了lombok,如果你沒有用lombok依賴和IDE插件,你要重寫getter、Setter方法:
代碼稍長,可以復制在IDEA中查看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
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 轉換器 * @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) { //創建客戶端參數 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.get( 0 ), mongoCredential, options); //集群模式 if (serverAddresses.size() > 1 ) { mongoClient = new MongoClient(serverAddresses, new ArrayList<>(Arrays.asList(mongoCredential))); } /** ps: 創建非認證客戶端*/ //MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions); return new SimpleMongoDbFactory(mongoClient, properties.getDatabase()); } /** * mongo客戶端參數配置 * @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 { /** 基礎連接參數 */ 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幫你做得事:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
/** * 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); @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自定義連接池內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/keeya/p/11992267.html