首页

通过JedisPool设计分析说明Apache的GenericObjectPool对象池的通用性

标签:apache,pools,对象池,GenericObjectPool,BaseObjectPool     发布时间:2017-02-20   

一、前言

通过分析JedisPool缓存池设计分析apache的GenericObjectPool通用性,其中提供了GenericKeyedObjectPool,SoftReferenceObjectPool和GenericObjectPool三种对象池,但是其中GenericObjectPool是最常用的对象池,具体如下图所示

通过JedisPool设计分析说明Apache的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@}