本文主要讲解的是本人代码设计的演变过程,以及使用工厂设计模式解决了什么问题

   首先,我先介绍一下我将其设计为工厂设计模式的背景

   我司的项目一直以来RedisTemplate来操作redis,以前一直都是在一个redis的库中所以没有什么影响,但是今天需要随时切换redis的DB,我上网查阅了一些资料,没有找到关于RedisTemplate切换DB的方式,所以我就重新封装了一下Jedis

   其中有一个Jedis的连接池,我看一下源码,里面几乎全部都是构造函数

设计模式(一) 工厂设计模式实战

   这个连接池需要自己创建,这个让我有些头疼

设计模式(一) 工厂设计模式实战

  这个是初期的代码,使用的静态代码块初始化数据,虽然数据只初始化了一次,但是只要调用updateRedisDB()方法就会创建一个JedisPool,但是我又不能把它放到代码块中,因为这样我就无法灵活的选择JedisPool的构造函数了,所以单例就也被我淘汰了(ps:因为上面截图部分为比较low的代码,所以我没有贴出来,只是截图.....)

  最后我决定使用工厂模式来解决这个问题,话不多说,上代码


import com.shengya.service.utils.PropertiesUtils;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 创建JedisPool的工厂
 *
 * @author wise
 * @since CreateDate   2018-05-11 16:11:30
 */
public class JedisPoolFactory {

    private static Integer PORT;

    private static String HOST;

    private static Integer TIMEOUT = 10000;

    private static String PASSWORD;

    //缓存容器
    private static Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();

    /**  静态代码块初始化参数
     * @author wise
     * @date 2018/5/11 0011 16:30
     * @param null
     * @return
     */
    static {
        Properties p = PropertiesUtils.getProperties();
        try {
            HOST = p.getProperty("redisHost");
            String redisPort = p.getProperty("redisPort");
            if (!StringUtils.isEmpty(redisPort)) {
                PORT = Integer.parseInt(redisPort);
            }
            PASSWORD = p.getProperty("redisPass");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    /**
     * 获取JedisPool对象
     *
     * @param name
     * @param arms
     * @return redis.clients.jedis
     * @author wise
     * @date 2018/5/11 0011 15:32
     */
    public JedisPool getJedis(String name, Object... arms) {
        JedisPoolConfig config = null;
        JedisPool jedisPool = null;
        if ("dataBase".equals(name)) {
            ReentrantLock lock = new ReentrantLock();
            Condition condition =  lock.newCondition();

            Integer dataBase = 0;
            if (arms != null && arms.length > 0) {
                Object index = arms[0];
                //判断当前参数是否是Integer类型
                if (index instanceof Integer) {
                    dataBase = (int) index;
                }
            }
            //查询缓存中是否存在该DB的连接池
            if (cacheMap.get(name + dataBase) != null) {
                Object obj = cacheMap.get(name);
                if (obj instanceof JedisPool) {
                    jedisPool = (JedisPool)obj;
                }
            }
            //缓存中不存在该DB的连接池
            if (jedisPool == null) {
                config = new JedisPoolConfig();
                config.setMaxIdle(5);
                config.setTestOnBorrow(false);
                jedisPool = new JedisPool(config, HOST, PORT, TIMEOUT, PASSWORD, dataBase);
                cacheMap.put(name, jedisPool);
                cacheMap.put(name + dataBase, dataBase);
            }
        }
        //如果拓展jedisPool,请在后面添加
        return jedisPool;
    }
}

     我还是选择先用静态代码块来初始化参数,getJedis()方法我使用一个name参数来判断当前要创建的JedisPool,使用可变参数来传递数据,为避免同样的redis库重复创建jedisPool,我使用了ConcurrentHashMap做缓存,每次在创建一次先进行一次判断,以后如果需要再创建其它的JedisPool的话直接在后面加上else if即可,拓展起来非常方便

    如果您对我的看法有更好的意见或建议,请随时私信我或者在评论区留言,不吝赐教

版权声明:本文为博主原创文章,转载请注明出处(https://blog.csdn.net/F1004145107/article/details/80281722)

  

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-06
  • 2021-06-17
  • 2021-05-11
  • 2021-06-06
  • 2022-12-23
猜你喜欢
  • 2021-07-03
  • 2021-04-18
  • 2021-06-23
  • 2021-10-03
  • 2021-11-12
  • 2021-09-28
  • 2021-11-29
相关资源
相似解决方案