jedis源码分析——JedisPool

jedis是Redis官网推荐的java客户端实现。下面分析一下JedisPool的实现

JedisPool源码如下:

package redis.clients.jedis;

import org.apache.commons.pool.impl.GenericObjectPool.Config;
import redis.clients.util.Pool;

public class JedisPool extends Pool<Jedis>
{
  public JedisPool(GenericObjectPool.Config poolConfig, String host)
  {
    this(poolConfig, host, 6379, 2000, null);
  }

  public JedisPool(String host, int port)
  {
    super(new GenericObjectPool.Config(), new JedisFactory(host, port, 2000, null));
  }

  public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout, String password)
  {
    super(poolConfig, new JedisFactory(host, port, timeout, password));
  }

  public JedisPool(GenericObjectPool.Config poolConfig, String host, int port)
  {
    this(poolConfig, host, port, 2000, null);
  }

  public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout)
  {
    this(poolConfig, host, port, timeout, null);
  }
}

 JedisPool继承了Pool,Pool的源码如下:

package redis.clients.util;

import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;

public abstract class Pool<T>
{
  private final GenericObjectPool internalPool;

  public Pool(GenericObjectPool.Config poolConfig, PoolableObjectFactory factory)
  {
    this.internalPool = new GenericObjectPool(factory, poolConfig);
  }

  public T getResource()
  {
    try {
      return this.internalPool.borrowObject();
    } catch (Exception e) {
      throw new JedisConnectionException("Could not get a resource from the pool", e);
    }
  }

  public void returnResource(T resource)
  {
    try {
      this.internalPool.returnObject(resource);
    } catch (Exception e) {
      throw new JedisException("Could not return the resource to the pool", e);
    }
  }

  public void returnBrokenResource(T resource)
  {
    try {
      this.internalPool.invalidateObject(resource);
    } catch (Exception e) {
      throw new JedisException("Could not return the resource to the pool", e);
    }
  }

  public void destroy()
  {
    try {
      this.internalPool.close();
    } catch (Exception e) {
      throw new JedisException("Could not destroy the pool", e);
    }
  }
}

 至此我们已经清楚了,JedisPool使用了apache的GenericObjectPool来作为redis连接管理pool。GenericObjectPool的官方地址是:http://commons.apache.org/pool/

JedisFactory是PoolableObjectFactory的子类,PoolableObjectFactory提供了可以被Pool管理的对象的若干生命周期方法,JedisFactory的源码如下:

package redis.clients.jedis;

import org.apache.commons.pool.BasePoolableObjectFactory;

class JedisPool$JedisFactory extends BasePoolableObjectFactory
{
  private final String host;
  private final int port;
  private final int timeout;
  private final String password;

  public JedisPool$JedisFactory(String host, int port, int timeout, String password)
  {
    this.host = host;
    this.port = port;
    this.timeout = ((timeout > 0) ? timeout : -1);
    this.password = password;
  }

  public Object makeObject()
    throws Exception
  {
    Jedis jedis;
    if (this.timeout > 0)
      jedis = new Jedis(this.host, this.port, this.timeout);
    else {
      jedis = new Jedis(this.host, this.port);
    }

    jedis.connect();
    if (null != this.password) {
      jedis.auth(this.password);
    }
    return jedis;
  }

  public void destroyObject(Object obj) throws Exception {
    if (obj instanceof Jedis) {
      Jedis jedis = (Jedis)obj;
      if (!(jedis.isConnected())) return;
      try {
        try {
          jedis.quit();
        } catch (Exception e) {
        }
        jedis.disconnect();
      }
      catch (Exception e)
      {
      }
    }
  }

  public boolean validateObject(Object obj) {
    if (obj instanceof Jedis) {
      Jedis jedis = (Jedis)obj;
      try {
        return ((jedis.isConnected()) && (jedis.ping().equals("PONG")));
      } catch (Exception e) {
        return false;
      }
    }
    return false;
  }
}
 上面代码非常清楚地说明了JedisFactory如何构建、销毁、验证Jedis对象。这些生命周期方法会被GenericObjectPool 的borrowObject,returnObject,invalidateObject等方法调用。

相关推荐