前面介绍了mongodb集群安装方法, 主要是docker下安装副本集的, 然后介绍了spring 访问副本集的方法。
一. 准备工作
1. 您需要用docker 安装mongodb的副本集 集群, 参考: Docker部署一个MongoDB集群 通过这个您才有了可以操作的对象
2. 您需要看过前面的 spring 访问mongodb的文章, 这样您才能配置相关权限,和创建好数据库等, 请参考: spring访问mongodb集群
本文在最后会 给出相关代码
二. 遇到的问题
正常情况下在spring boot中配置 mongodb的链接可以用
spring.data.mongodb.uri=mongodb://localhost/test 方式 spring.data.mongodb.username=mytest03 spring.data.mongodb.password=password
通过上面的uri我们指定了 连接, 下面的是用户名和密码 但是这个方式紧急能指定一个 mongodb的服务器, 无法指定多个 经过搜索, 发现mongodb还有别的配置方式
下面是在 appendix-application-properties.adoc 文件中搜索到全部mongodb的配置
# MONGODB ({sc-spring-boot-autoconfigure}/mongo/MongoProperties.{sc-ext}[MongoProperties])
spring.data.mongodb.authentication-database= # Authentication database name.
spring.data.mongodb.database=test # Database name.
spring.data.mongodb.field-naming-strategy= # Fully qualified name of the FieldNamingStrategy to use.
spring.data.mongodb.grid-fs-database= # GridFS database name.
spring.data.mongodb.host=localhost # Mongo server host. Cannot be set with uri.
spring.data.mongodb.password= # Login password of the mongo server. Cannot be set with uri.
spring.data.mongodb.port=27017 # Mongo server port. Cannot be set with uri.
spring.data.mongodb.reactive-repositories.enabled=true # Enable Mongo reactive repositories.
spring.data.mongodb.repositories.enabled=true # Enable Mongo repositories.
spring.data.mongodb.uri=mongodb://localhost/test # Mongo database URI. Cannot be set with host, port and credentials.
spring.data.mongodb.username= # Login user of the mongo server. Cannot be set with uri.另外这个文件还有很多 其他的配置, 大家都可以参考, 这个配置文件在spring boot的 源代码中
1. 探索方法
采用下面的写法
spring.data.mongodb.uri=mongodb://mytest03:password@192.168.128.189:27017,mytest03:password@192.168.128.132:27017,mytest03:password@192.168.128.133:27017
结果运行时报解析配置异常
2. 探索方法
spring.data.mongodb.uri=mongodb://192.168.128.189:27017,192.168.128.132:27017,192.168.128.133:27017/mytest03
采用了上面的写法仍然出问题
最后通过搜索可以发现, 可以采用覆盖spring boot bean的方法覆盖掉系统默认呢的mongodb client的处理方法
三. 覆盖spring boot的bean的方法解决mongodb的问题
1. 覆盖的必要性

如上图, 在默认的 mongodb副本集链接中, 客户需要连接到主的 机器上, 但是若是副本集的主和从发生了切换, 就会造成 原来连接的不是主了, 因此影响工作。
在mongodb的客户端中支持同时连接多个的(对副本集进行支持的)
List<ServerAddress> addresses = new ArrayList<ServerAddress>();
ServerAddress address1 = new ServerAddress("192.168.128.189", 27017);
ServerAddress address2 = new ServerAddress("192.168.128.132", 27017);
ServerAddress address3 = new ServerAddress("192.168.128.133", 27017);
addresses.add(address1);
addresses.add(address2);
addresses.add(address3);
MongoCredential credential = MongoCredential.createMongoCRCredential("mytest03", "mytest03", "password".toCharArray());
MongoClient client = new MongoClient(addresses, Arrays.asList(credential));
return client;上面是连接方法
但是, 由于前面spring boot的配置中仅仅能配置一个ip地址, 因此对上面的多地址的客户端连接不支持, 因此spring boot的默认mongodb方法不能满足需求
2. 自定义spring bean的方法解决问题
代码如下:
package cn.iigrowing.study.mongodb;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
@Component
public class MongoClass {
@Bean
@ConditionalOnMissingBean(MongoClient.class)
public MongoClient getMongodbClients() {
List<ServerAddress> addresses = new ArrayList<ServerAddress>();
ServerAddress address1 = new ServerAddress("192.168.128.189", 27017);
ServerAddress address2 = new ServerAddress("192.168.128.132", 27017);
ServerAddress address3 = new ServerAddress("192.168.128.133", 27017);
addresses.add(address1);
addresses.add(address2);
addresses.add(address3);
MongoCredential credential = MongoCredential.createMongoCRCredential("mytest03", "mytest03", "password".toCharArray());
MongoClient client = new MongoClient(addresses, Arrays.asList(credential));
return client;
}
}
在上面代码中重点要注意的是:
@Bean 这个声明了一个bean
@ConditionalOnMissingBean(MongoClient.class) 这个非常重要,
这个是告诉系统, 下面的bean是要替换系统默认的那个bean的(mongodb)
最后
@Component这个是告诉spring boot 要扫描着类, 否则,前面的注解都没用。
本文的配置都是写在程序代码中的, 后面还会修改进行, 参数配置, 稍后提供相关的文档等


