重写mongoclient,适配集群、单点配置

最近有一个需求,需要在配置文件中配置mongo的信息,如果是集群就创建集群客户端,如果是单点,就创建单点的客户端(springboot项目)。

知识储备:
  1. 首先我们需要去掉springboot的mongo自动装配。
  2. 我们需要判断ip是否为多个,进而生成对应的客户端。
  3. 如果我们使用的是mongotemplete,需要重写这个bean,因为我们已经不让springboot自动装配了。

1.去掉springboot的自动装配mongo(Application.java)

package com.jd.jr;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.*;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * 
 *
 * @author: 垃圾外包
 * @date: 2020/12/10
 */
 /**
 * exclude 排除不让springboot自动加载的类
 */
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, 
public class BootApplication {
    private static final Logger logger = LoggerFactory.getLogger(BootApplication.class);

    public static void main(String[] args) {
        logger.info("应用启动开始");
        SpringApplication.run(BootApplication.class, args);
        logger.info("应用启动成功");
    }
}

2.在配置中,配置对应的信息,规则可以自定义(application.properties)

# 如果是集群,多个IP直间用英文,分割 例如下一行
# mongo.host=10.10.10.10,10.10.10.11,10.10.10.12
mongo.host=10.10.10.10
mongo.username=admin
mongo.password=admin
mongo.hostport=27017
mongo.dbname=test
mongo.connectTimeout=1000
mongo.socketTimeout=1500
# 如果想配置其他信息,在此配置

3.编写生成client的mongo配置(MongoInit.java)


package com.jd.jr.abtest.web.config;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import lombok.Setter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 不想写注释可以吗?
 * @Author: 垃圾外包
 * @Date: 2020/12/9 16:30
 **/
public class MongodbInit {

    private static volatile MongodbInit mongodbInit;

    private MongodbInit() {
    }

    public static MongodbInit getMongoInit() {
        if (mongodbInit == null) {
            synchronized (MongodbInit.class) {
                if (mongodbInit == null) {
                    mongodbInit = new MongodbInit();
                }
            }
        }
        return mongodbInit;
    }

    @Setter
    private String ip;

    @Setter
    private Integer port;

    @Setter
    private String databaseName;

    @Setter
    private String userName;

    @Setter
    private String password;

    @Setter
    private Integer connectTimeout;

    @Setter
    private Integer socketTimeout;

    private static final String SPLITTER = ",";

    private static MongoClient mongoClient;

    public MongoClient getMongoDbClient() {
        if (mongoClient==null){
            init();
        }
        return mongoClient;
    }

    private void init() {
        Assert.notNull(ip, "ip cannot be null");
        Assert.notNull(databaseName, "databaseName cannot be null");
        boolean noCredit = StringUtils.isEmpty(userName) && StringUtils.isEmpty(password);
        if (!ip.contains(SPLITTER)) {
            if (noCredit) {
                mongoClient = new MongoClient(new ServerAddress(ip, port), MongoClientOptions.builder().connectTimeout(connectTimeout).socketTimeout(socketTimeout).build());
            } else {
                mongoClient = new MongoClient(new ServerAddress(ip, port), MongoCredential.createCredential(userName, databaseName, password.toCharArray()), MongoClientOptions.builder().connectTimeout(connectTimeout).socketTimeout(socketTimeout).build());
            }
        } else {
            String[] ips = ip.split(SPLITTER);
            List<ServerAddress> serverAddresses = new ArrayList<>();
            for (String ip : ips) {
                serverAddresses.add(new ServerAddress(ip, port));
            }
            if (noCredit) {
                mongoClient = new MongoClient(serverAddresses, MongoClientOptions.builder().connectTimeout(connectTimeout).socketTimeout(socketTimeout).build());
            } else {
                mongoClient = new MongoClient(serverAddresses, MongoCredential.createCredential(userName, databaseName, password.toCharArray()), MongoClientOptions.builder().connectTimeout(connectTimeout).socketTimeout(socketTimeout).build());
            }
        }
    }
}

4.我们自己注入 mongotemplate(MongoConfig.java)

package com.jd.jr.abtest.web.config;

import com.mongodb.MongoClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
 * @Description:
 * @Author: fudongyang
 * @Date: 2020/12/9 16:14
 **/
@Configuration
public class MongoConfig {

    @Value("${mongo.host}")
    private String host;
    @Value("${mongo.username}")
    private String username;
    @Value("${mongo.password}")
    private String password;
    @Value("${mongo.hostport}")
    private int hostport;
    @Value("${mongo.dbname}")
    private String dbname;
    @Value("${mongo.connectTimeout}")
    private int connectTimeout;
    @Value("${mongo.socketTimeout}")
    private int socketTimeout;

    @Bean("mongoDataAnalytics")
    public MongoTemplate setMongoTemplate() {
        MongodbInit mongo = MongodbInit.getMongoInit();
        mongo.setIp(host);
        mongo.setUserName(username);
        mongo.setPassword(password);
        mongo.setPort(hostport);
        mongo.setDatabaseName(dbname);
        mongo.setConnectTimeout(connectTimeout);
        mongo.setSocketTimeout(socketTimeout);
        MongoClient mongoDbClient = mongo.getMongoDbClient();
        return new MongoTemplate(mongoDbClient, dbname);
    }
}

5.测试,连接成功,不过日志报了一个info。

info org.mongodb.driver.cluster : Exception in monitor thread while connection ip地址

声明:我引用的mongo是spring-data-mongo-2.1.3。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值