JedisPool源代码

1,JedisPool的使用

//WHEN_EXHAUSTED_FAIL = 0; 直接抛出异常throw new NoSuchElementException("Pool exhausted");
//WHEN_EXHAUSTED_BLOCK = 1;borrowObject()将会阻塞,直到有可用新的或者空闲的object为止,或者如果配置了maxWait,
//如果请求阻塞超时,将抛出NoSuchElementException.如果maxWait为负数,请求将会无限制的阻
//塞下去,默认配置。
//WHEN_EXHAUSTED_GROW = 2;borrowObject()将会继续创建新的对象,并返回,因此,pool维护的对像数将超出maxActive;

 

public String set(String key, String value) {
	Jedis jedis = null;
	boolean success = true;
	try {
		jedis = this.pool.getResource();
		return jedis.set(key, value);
	} catch (JedisException e) {
		success = false;
		if(jedis != null){
		pool.returnBrokenResource(jedis);
		}
		throw e;
	} finally {
		if(success && jedis != null){
		this.pool.returnResource(jedis);
	}
}

获取Jedis

pool.getResource();

这个可以直接看Pool的getResource方法,

最终还是GenericObjectPool的borrowObject()方法借用对象

 

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

用完归还,调用的是GenericObjectPool的returnObject()方法

pool.returnResource(jedis)

 

//JedisPool.java
public void returnResource(final BinaryJedis resource) {
	returnResourceObject(resource);
}
//Pool.java
public void returnResourceObject(final Object resource) {
	try {
		internalPool.returnObject(resource);
	} catch (Exception e) {
		throw new JedisException("Could not return the resource to the pool", e);
	}
}

出错,调用的是GenericObjectPool的invalidateObject()方法

最后在JedisFactory的destroyObject()中调用jedis.quit()请求Server关闭连接

pool.returnBrokenResource(jedis)

 

//JedisPool.java
public void returnBrokenResource(final BinaryJedis resource) {
	returnBrokenResourceObject(resource);
}
//Pool.java
protected void returnBrokenResourceObject(final Object resource) {
	try {
		//失效
		internalPool.invalidateObject(resource);
	} catch (Exception e) {
		throw new JedisException(
		"Could not return the resource to the pool", e);
	}
}
//GenericObjectPool
public void invalidateObject(Object obj) throws Exception {
	try {
		if (this._factory != null)
		this._factory.destroyObject(obj);
	} finally {
		synchronized (this) {
			this._numActive -= 1;
			allocate();
		}
	}
}
//JedisFactory
public void destroyObject(final Object obj) throws Exception {
	if (obj instanceof Jedis) {
		final Jedis jedis = (Jedis) obj;
		if (jedis.isConnected()) {
			try {
				try {
					jedis.quit();
				} catch (Exception e) {
				}
				jedis.disconnect();
			} catch (Exception e) {
			}
		}
	}
}

JedisPool源代码

package redis.clients.jedis;

import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config;

import redis.clients.util.Pool;

public class JedisPool extends Pool {

	public JedisPool(final Config poolConfig, final String host) {
	    this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
	}
	
	public JedisPool(String host, int port) {
	    this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
	}
	
	public JedisPool(final String host) {
	    this(host, Protocol.DEFAULT_PORT);
	}
	
	public JedisPool(final Config poolConfig, final String host, int port,
	        int timeout, final String password) {
	    this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE);
	}
	
	public JedisPool(final Config poolConfig, final String host, final int port) {
	    this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
	}
	
	public JedisPool(final Config poolConfig, final String host, final int port, final int timeout) {
	    this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE);
	}
	
	public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password,
	                 final int database) {
	    super(poolConfig, new JedisFactory(host, port, timeout, password, database));
	}
	
	
	public void returnBrokenResource(final BinaryJedis resource) {
	    returnBrokenResourceObject(resource);
	}
	
	public void returnResource(final BinaryJedis resource) {
	    returnResourceObject(resource);
	}
	
	/**
	 * PoolableObjectFactory custom impl.
	 */
	private static class JedisFactory extends BasePoolableObjectFactory {
	    private final String host;
	    private final int port;
	    private final int timeout;
	    private final String password;
	    private final int database;
	
	    public JedisFactory(final String host, final int port,
	            final int timeout, final String password, final int database) {
	        super();
	        this.host = host;
	        this.port = port;
	        this.timeout = timeout;
	        this.password = password;
	        this.database = database;
	    }
	
	    public Object makeObject() throws Exception {
	        final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
	
	        jedis.connect();
	        if (null != this.password) {
	            jedis.auth(this.password);
	        }
	        if( database != 0 ) {
	            jedis.select(database);
	        }
	
	        return jedis;
	    }
	
	    public void destroyObject(final Object obj) throws Exception {
	        if (obj instanceof Jedis) {
	            final Jedis jedis = (Jedis) obj;
	            if (jedis.isConnected()) {
	                try {
	                    try {
	                        jedis.quit();
	                    } catch (Exception e) {
	                    }
	                    jedis.disconnect();
	                } catch (Exception e) {
	
	                }
	            }
	        }
	    }
	
	    public boolean validateObject(final Object obj) {
	        if (obj instanceof Jedis) {
	            final Jedis jedis = (Jedis) obj;
	            try {
	                return jedis.isConnected();/* && jedis.ping().equals("PONG");*/
	            } catch (final Exception e) {
	                return false;
	            }
	        } else {
	            return false;
	        }
	    }
	}
}

 其中JedisFactory继承自BasePoolableObjectFactory,只实现了3个方法

 

makeObject(),连接,new Socket()

 

destroyObject()--断开连接,

 

validateObject()--ping

 

Pool源代码

package redis.clients.util;

import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;

public abstract class Pool {

	private final GenericObjectPool internalPool;
	
	public Pool(final GenericObjectPool.Config poolConfig,
	        PoolableObjectFactory factory) {
	    this.internalPool = new GenericObjectPool(factory, poolConfig);
	}
	
	@SuppressWarnings("unchecked")
	public T getResource() {
	    try {
	        return (T) internalPool.borrowObject();
	    } catch (Exception e) {
	        throw new JedisConnectionException(
	                "Could not get a resource from the pool", e);
	    }
	}
	
	public void returnResourceObject(final Object resource) {
	    try {
	        internalPool.returnObject(resource);
	    } catch (Exception e) {
	        throw new JedisException(
	                "Could not return the resource to the pool", e);
	    }
	}
	
	public void returnBrokenResource(final T resource) {
	    returnBrokenResourceObject(resource);
	}
	
	public void returnResource(final T resource) {
	    returnResourceObject(resource);
	}
	
	protected void returnBrokenResourceObject(final Object resource) {
	    try {
	        //失效
	        internalPool.invalidateObject(resource);
	    } catch (Exception e) {
	        throw new JedisException(
	                "Could not return the resource to the pool", e);
	    }
	}
	
	public void destroy() {
	    try {
	        internalPool.close();
	    } catch (Exception e) {
	        throw new JedisException("Could not destroy the pool", e);
	    }
	}
}

 JedisPoolConfig源代码

public class JedisPoolConfig extends Config {
	public JedisPoolConfig() {
	// defaults to make your life with connection pool easier :)
	setTestWhileIdle(true);
	setMinEvictableIdleTimeMillis(60000);
	setTimeBetweenEvictionRunsMillis(30000);
	setNumTestsPerEvictionRun(-1);
	}
	
	public int getMaxIdle() {
	    return maxIdle;
	}
	
	public void setMaxIdle(int maxIdle) {
	    this.maxIdle = maxIdle;
	}
	
	public int getMinIdle() {
	    return minIdle;
	}
	
	public void setMinIdle(int minIdle) {
	    this.minIdle = minIdle;
	}
	
	public int getMaxActive() {
	    return maxActive;
	}
	
	public void setMaxActive(int maxActive) {
	    this.maxActive = maxActive;
	}
	
	public long getMaxWait() {
	    return maxWait;
	}
	
	public void setMaxWait(long maxWait) {
	    this.maxWait = maxWait;
	}
	
	public byte getWhenExhaustedAction() {
	    return whenExhaustedAction;
	}
	
	public void setWhenExhaustedAction(byte whenExhaustedAction) {
	    this.whenExhaustedAction = whenExhaustedAction;
	}
	
	public boolean isTestOnBorrow() {
	    return testOnBorrow;
	}
	
	public void setTestOnBorrow(boolean testOnBorrow) {
	    this.testOnBorrow = testOnBorrow;
	}
	
	public boolean isTestOnReturn() {
	    return testOnReturn;
	}
	
	public void setTestOnReturn(boolean testOnReturn) {
	    this.testOnReturn = testOnReturn;
	}
	
	public boolean isTestWhileIdle() {
	    return testWhileIdle;
	}
	
	public void setTestWhileIdle(boolean testWhileIdle) {
	    this.testWhileIdle = testWhileIdle;
	}
	
	public long getTimeBetweenEvictionRunsMillis() {
	    return timeBetweenEvictionRunsMillis;
	}
	
	public void setTimeBetweenEvictionRunsMillis(
	        long timeBetweenEvictionRunsMillis) {
	    this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
	}
	
	public int getNumTestsPerEvictionRun() {
	    return numTestsPerEvictionRun;
	}
	
	public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
	    this.numTestsPerEvictionRun = numTestsPerEvictionRun;
	}
	
	public long getMinEvictableIdleTimeMillis() {
	    return minEvictableIdleTimeMillis;
	}
	
	public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
	    this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
	}
	
	public long getSoftMinEvictableIdleTimeMillis() {
	    return softMinEvictableIdleTimeMillis;
	}
	
	public void setSoftMinEvictableIdleTimeMillis(
	        long softMinEvictableIdleTimeMillis) {
	    this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
	}
}

 

猜你喜欢

转载自ily.iteye.com/blog/2247212