一、前言
通过分析JedisPool缓存池设计分析apache的GenericObjectPool通用性,其中提供了GenericKeyedObjectPool,SoftReferenceObjectPool和GenericObjectPool三种对象池,但是其中GenericObjectPool是最常用的对象池,具体如下图所示
二、源码分析
1. redis.clients.jedis.JedisPool源码如下所示
import org.apache.commons.pool.BasePoolableObjectFactory;@b@import org.apache.commons.pool.impl.GenericObjectPool.Config;@b@import redis.clients.util.Pool;@b@@b@public class JedisPool extends Pool<Jedis> {@b@ public JedisPool(GenericObjectPool.Config poolConfig, String host)@b@ {@b@ this(poolConfig, host, 6379, 2000, null, 0);@b@ }@b@@b@ public JedisPool(String host, int port) {@b@ this(new GenericObjectPool.Config(), host, port, 2000, null, 0);@b@ }@b@@b@ public JedisPool(String host) {@b@ this(host, 6379);@b@ }@b@@b@ public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout, String password)@b@ {@b@ this(poolConfig, host, port, timeout, password, 0);@b@ }@b@@b@ public JedisPool(GenericObjectPool.Config poolConfig, String host, int port) {@b@ this(poolConfig, host, port, 2000, null, 0);@b@ }@b@@b@ public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout) {@b@ this(poolConfig, host, port, timeout, null, 0);@b@ }@b@@b@ public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout, String password, int database)@b@ {@b@ super(poolConfig, new JedisFactory(host, port, timeout, password, database));@b@ }@b@@b@ public void returnBrokenResource(BinaryJedis resource)@b@ {@b@ returnBrokenResourceObject(resource);@b@ }@b@@b@ public void returnResource(BinaryJedis resource) {@b@ returnResourceObject(resource);@b@ }@b@@b@ private static class JedisFactory extends BasePoolableObjectFactory@b@ {@b@ private final String host;@b@ private final int port;@b@ private final int timeout;@b@ private final String password;@b@ private final int database;@b@@b@ public JedisFactory(String host, int port, int timeout, String password, int database)@b@ {@b@ this.host = host;@b@ this.port = port;@b@ this.timeout = timeout;@b@ this.password = password;@b@ this.database = database;@b@ }@b@@b@ public Object makeObject() throws Exception {@b@ Jedis jedis = new Jedis(this.host, this.port, this.timeout);@b@@b@ jedis.connect();@b@ if (null != this.password)@b@ jedis.auth(this.password);@b@@b@ if (this.database != 0) {@b@ jedis.select(this.database);@b@ }@b@@b@ return jedis;@b@ }@b@@b@ public void destroyObject(Object obj) throws Exception {@b@ if (obj instanceof Jedis) {@b@ Jedis jedis = (Jedis)obj;@b@ if (jedis.isConnected())@b@ try {@b@ try {@b@ jedis.quit();@b@ } catch (Exception e) {@b@ }@b@ jedis.disconnect();@b@ }@b@ catch (Exception e)@b@ {@b@ }@b@ }@b@ }@b@@b@ public boolean validateObject(Object obj) {@b@ if (obj instanceof Jedis) {@b@ Jedis jedis = (Jedis)obj;@b@ try {@b@ return ((jedis.isConnected()) && (jedis.ping().equals("PONG")));@b@ } catch (Exception e) {@b@ return false;@b@ }@b@ }@b@ return false;@b@ }@b@ }@b@}
2. redis.clients.util.Pool源码如下
import org.apache.commons.pool.PoolableObjectFactory;@b@import org.apache.commons.pool.impl.GenericObjectPool;@b@import org.apache.commons.pool.impl.GenericObjectPool.Config;@b@import redis.clients.jedis.exceptions.JedisConnectionException;@b@import redis.clients.jedis.exceptions.JedisException;@b@@b@public abstract class Pool<T> {@b@@b@ private final GenericObjectPool internalPool;@b@@b@ public Pool(GenericObjectPool.Config poolConfig, PoolableObjectFactory factory)@b@ {@b@ this.internalPool = new GenericObjectPool(factory, poolConfig);@b@ }@b@@b@ public T getResource()@b@ {@b@ try {@b@ return this.internalPool.borrowObject();@b@ } catch (Exception e) {@b@ throw new JedisConnectionException("Could not get a resource from the pool", e);@b@ }@b@ }@b@@b@ public void returnResourceObject(Object resource)@b@ {@b@ try {@b@ this.internalPool.returnObject(resource);@b@ } catch (Exception e) {@b@ throw new JedisException("Could not return the resource to the pool", e);@b@ }@b@ }@b@@b@ public void returnBrokenResource(T resource)@b@ {@b@ returnBrokenResourceObject(resource);@b@ }@b@@b@ public void returnResource(T resource) {@b@ returnResourceObject(resource);@b@ }@b@@b@ protected void returnBrokenResourceObject(Object resource) {@b@ try {@b@ this.internalPool.invalidateObject(resource);@b@ } catch (Exception e) {@b@ throw new JedisException("Could not return the resource to the pool", e);@b@ }@b@ }@b@@b@ public void destroy()@b@ {@b@ try {@b@ this.internalPool.close();@b@ } catch (Exception e) {@b@ throw new JedisException("Could not destroy the pool", e);@b@ }@b@ }@b@ @b@}