天天看点

spring中集成使用jedis(2)

本文主要就spring注入的连接池使用问题,做简要说明。

使用过JedisPool的同学会发现,通过JedisPool获取资源,在使用完毕后,需要显式的将资源放回连接池中,

如下:

JedisPool jedisPool;
Jedis jedis = jedisPool.getResource();
//操作
jedisPool.returnResource(jedis);
           

如果未显示的回收资源,则在连接池中资源使用完毕后,系统会出现阻塞。

因为如果使用连接池,就相当于将客户端连接托管给池,而池中资源又是事先设定,及有限资源,

那么在资源都被占用,且无人回收时,就会出现一直阻塞等待资源。

但是在每个操作后都显示的调用资源回收,又显得代码臃肿,此处建议考虑通过动态代理实现,及在每次操作前

通过代理获取资源,操作后再将资源回收。代码设计如下:

public class RedisService implements IMemCached {
	/**
	 * 连接池
	 */
	@Getter
	@Setter
	private JedisPool jedisPool;
	@Getter
	@Setter
        private Jedis jedis;
    /**
     * 
     * @Title: initJedis
     * @Description: 从连接池获取连接
     */
	public void initJedis(){
    	this.jedis = jedisPool.getResource();
    }
	/**
	 * 
	 * @Title: returnJedis
	 * @Description: 将连接放回连接池
	 */
    public void returnJedis(){
    	jedisPool.returnResource(jedis);
    }
    
	@Override
	public boolean setValue(String key, Object value)
			throws MemcachedOpException {
		return OK.equals(jedis.set(key,
				null == value ? StringUtils.EMPTY : value.toString()));
	}

	@Override
	public boolean setValue(String key, Object value, int expTime)
			throws MemcachedOpException {
		return  OK.equals(jedis.setex(key,expTime,
				null == value ? StringUtils.EMPTY : value.toString()));
	}

	@Override
	public Object getValue(String key) throws MemcachedOpException {
		return jedis.get(key);
	}

	@Override
	public Object getValue(String key, long timeout)
			throws MemcachedOpException {
		return getValue(key);
	}

	public List<String> getValue(String... keys) throws MemcachedOpException {
		return jedis.mget(keys);
	}

    /**
     * 
     * @Title: sadd
     * @Description: 添加一个或者多个元素到集合(set)里
     * @param key
     * @param members
     * @return
     */
    public boolean sadd(final String key,String... members) throws MemcachedOpException{
		return 1==jedis.sadd(key, members);
    }
    /**
     * 
     * @Title: sRandomMember
     * @Description: 从集合里面随机获取一个值
     * @param key
     * @return
     */
    public String sRandomMember(final String key) throws MemcachedOpException{
    	return jedis.srandmember(key);
    }
	
	

	@Override
	public IMemCached getProxy() {
		return new ProxyHandler().bind(this);
	}
	@Override
	public void flush() throws MemcachedFlushException {
          jedis.flushDB();		
	}
	
}
/**
 * 动态代理类 用于解决jedis需手工放回连接池的问题
 * @author guozb
 *
 */
class ProxyHandler implements InvocationHandler{
    private RedisService redis;
    /**
     * 
     * @Title: bind
     * @Description: 绑定代理对象
     * @param imem
     * @return
     */
    public IMemCached bind(RedisService imem){
    	this.redis = (RedisService) imem;
    	return (IMemCached)Proxy.newProxyInstance(RedisService.class.getClassLoader(), RedisService.class.getInterfaces(), this);
    }
	@Override
	public Object invoke(Object arg0, Method arg1, Object[] arg2)
			throws Throwable {
		//从连接池获取资源
		redis.initJedis();
		Object obj = arg1.invoke(redis, arg2);
		//将资源放回连接池
		redis.returnJedis();
		return obj;
	}
	
}
           

这样在使用时,通过调用getProxy()进行具体操作即可。

继续阅读