缓存工厂-CacheManager
2015-12-04 09:12
260 查看
记录下项目中用到的缓存的功能,个人感觉这种实现方式还是挺不错的,该实现方式是通过结合spring的IOC容器进行bean管理。
1. 缓存类型配置(这里实现了两种memcached和redis),因为是结合spring使用,所以这个类型配置就可以像数据库连接源那样在properties文件中进行配置,在config.properties配置文件中的memcached配置如下:
2. 缓存接口方法定义,接口中的方法个数可根据实际情况进行添加或删减:
2. 缓存工厂类实现
4. redis的实现
5. spring中配置缓存工厂实体bean的生成
这样在其他地方就可以通过cacheManager这个实体bean去使用缓存的功能了
1. 缓存类型配置(这里实现了两种memcached和redis),因为是结合spring使用,所以这个类型配置就可以像数据库连接源那样在properties文件中进行配置,在config.properties配置文件中的memcached配置如下:
#缓存类型 cache.provinder=memcached #缓存服务器地址和端口 cache.addresses=172.16.1.114:11211 #连接池大小 cache.poolsize=1
2. 缓存接口方法定义,接口中的方法个数可根据实际情况进行添加或删减:
public interface CacheManager { /** * 保存键值并指定存储时长,单位秒。 * @param key * @param value * @param duration * @return */ void set(String key, String value, int duration); /** * 保存键值并指定存储时长和时长单位 * @param key * @param value * @param duration * @param unit * @return */ void set(String key, String value, int duration, TimeUnit unit); /** * 永久保存键值 * @param key * @param value * @return */ void set(String key, String value); /** * 根据键获取值 * @param key * @return null表示没有找到 */ String get(String key); /** * 根据键删除对应键值对 * @param key * @return */ void delete(String key); /** * 获取一个计数器,增加相应的值并返回 * @param counter 计数器键名 * @param incrBy 增加的值 * @param defaultValue 计数器默认初始值 * @return */ long incrementAndGet(String counter, long incrBy, long defaultValue); /** * 获取一个计数器,减少相应的值并返回 * @param counter 计数器键名 * @param decrBy 减少的值 * @param defaultValue 计数器默认初始值 * @return */ long decrementAndGet(String counter, long decrBy, long defaultValue); /** * 关掉链接,释放资源 */ void shutdown(); }
2. 缓存工厂类实现
public class CacheManagerFactoryBean implements FactoryBean<CacheManager>{ private Logger log = LoggerFactory.getLogger(CacheManagerFactoryBean.class); private String provinder; private String addresses; private int poolsize; private CacheManager cm; public CacheManager getObject() throws Exception { if("memcached".equals(provinder)){ addresses = addresses.replaceAll("(,\\s*|\\s+)", " "); cm = new MemcachedCacheManager(addresses, poolsize); return cm; }else if("redis".equals(provinder)){ cm = new RedisCacheManager(addresses, poolsize); return cm; }else{ throw new Exception("缓存服务器提供商不正确,请设置config.properties中的cache.provinder,值为memcached或redis"); } } public void shutdown(){ log.info("shutdown cache manager."); cm.shutdown(); } public Class<?> getObjectType() { return CacheManager.class; } public boolean isSingleton() { return true; } public String getAddresses() { return addresses; } public void setAddresses(String addresses) { this.addresses = addresses; } public int getPoolsize() { return poolsize; } public void setPoolsize(int poolsize) { this.poolsize = poolsize; } public String getProvinder() { return provinder; } public void setProvinder(String provinder) { this.provinder = provinder; } }3. memcached的实现
import java.io.IOException; import net.rubyeye.xmemcached.MemcachedClient; import net.rubyeye.xmemcached.MemcachedClientBuilder; import net.rubyeye.xmemcached.XMemcachedClientBuilder; import net.rubyeye.xmemcached.utils.AddrUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MemcachedCacheManager implements CacheManager { private Logger log = LoggerFactory.getLogger(MemcachedCacheManager.class); private MemcachedClient client; public MemcachedCacheManager(String addresses, int poolsize){ MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(addresses)); builder.setConnectionPoolSize(poolsize); try { client = builder.build(); } catch (IOException e) { log.error("failed to build memcached client params:"); log.error("[addresses:{}, poolsize:{}]", new Object[]{addresses, poolsize}); log.error("failed to build memcached client details:", e); throw new RuntimeException(e); } } public void delete(String key){ try { client.delete(key); } catch(Exception e){ log.error("memcached delete failed params:"); log.error("[key:{}]", new Object[]{key}); log.error("memcahced delete failed details:", e); throw new RuntimeException(e); } } public String get(String key){ try { return client.get(key); } catch(Exception e){ log.error("memcached get failed params:"); log.error("[key:{}]", new Object[]{key}); log.error("memcahced get failed details:", e); throw new RuntimeException(e); } } public void set(String key, String value){ set(key, value, 0); } public void set(String key, String value, int duration) { try { client.set(key, duration, value); } catch(Exception e){ log.error("memcached set failed params:"); log.error("[key:{}, value:{}, duration:{}]", new Object[]{key, value, duration}); log.error("memcached set failed details:", e); throw new RuntimeException(e); } } public void set(String key, String value, int duration, TimeUnit unit) { set(key, value, duration*unit.getValue()); } public long incrementAndGet(String counter, long incrBy, long defaultValue) { try { return client.incr(counter, incrBy, defaultValue); } catch(Exception e){ log.error("memcached incr failed params:"); log.error("[counter:{}, incrBy:{}, defaultValue:{}]", new Object[]{counter, incrBy, defaultValue}); log.error("memcached incr failed details:", e); throw new RuntimeException(e); } } public long decrementAndGet(String counter, long decrBy, long defaultValue) { try { return client.decr(counter, decrBy, defaultValue); } catch(Exception e){ log.error("memcached decr failed params:"); log.error("[counter:{}, decrBy:{}, defaultValue:{}]", new Object[]{counter, decrBy, defaultValue}); log.error("memcached decr failed details:", e); throw new RuntimeException(e); } } public void shutdown() { try { client.shutdown(); } catch (IOException e) { log.error("failed to shutdown memcached client.", e); } } }
4. redis的实现
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.Transaction; public class RedisCacheManager implements CacheManager { private Logger log = LoggerFactory.getLogger(RedisCacheManager.class); private JedisPool pool; public RedisCacheManager(String addresses, int poolsize){ try{ String host = addresses.split(":")[0]; String port = addresses.split(":")[1]; JedisPoolConfig config = new JedisPoolConfig(); config.setMaxActive(poolsize); pool = new JedisPool(config, host, Integer.valueOf(port)); }catch(Exception e){ log.error("failed to build redis client params:"); log.error("[addresses:{}, poolsize:{}]", new Object[]{addresses, poolsize}); log.error("failed to build redis client details:", e); throw new RuntimeException(e); } } public String get(String key) { Jedis jedis = null; boolean success = true; try{ jedis = pool.getResource(); String value = jedis.get(key); return value; }catch(Exception e){ // jedis 操作失败把无效的jedis 实例返回给池做销毁处理 success = false; pool.returnBrokenResource(jedis); log.error("redis get failed params:"); log.error("[key:{}]", new Object[]{key}); log.error("redis get failed details:", e); throw new RuntimeException(e); }finally{ if(success){ // jedis 操作成功,把jedis返回给池,得以重用 pool.returnResource(jedis); } } } public void set(String key, String value){ Jedis jedis = null; boolean success = true; try{ jedis = pool.getResource(); jedis.set(key, value); }catch(Exception e){ success = false; pool.returnBrokenResource(jedis); log.error("redis set failed params:"); log.error("[key:{}, value:{}]", new Object[]{key, value}); log.error("redis set failed details:", e); throw new RuntimeException(e); }finally{ if(success){ pool.returnResource(jedis); } } } public void set(String key, String value, int duration){ Jedis jedis = null; boolean success = true; try{ jedis = pool.getResource(); Transaction tx = jedis.multi(); tx.set(key, value); tx.expire(key, duration); tx.exec(); }catch(Exception e){ success = false; pool.returnBrokenResource(jedis); log.error("redis set failed params:"); log.error("[key:{}, value:{}, duration:{}]", new Object[]{key, value, duration}); log.error("redis set failed details:", e); throw new RuntimeException(e); }finally{ if(success){ pool.returnResource(jedis); } } } public void set(String key, String value, int duration, TimeUnit unit) { set(key, value, duration*unit.getValue()); } public void delete(String key){ Jedis jedis = null; boolean success = true; try{ jedis = pool.getResource(); jedis.del(key); }catch(Exception e){ success = false; pool.returnBrokenResource(jedis); log.error("redis delete failed params:"); log.error("[key:{}]", new Object[]{key}); log.error("redis delete failed details:", e); throw new RuntimeException(e); }finally{ if(success){ pool.returnResource(jedis); } } } public long incrementAndGet(String counter, long incrBy, long defaultValue) { Jedis jedis = null; boolean success = true; try{ jedis = pool.getResource(); long count = jedis.incrBy(counter, incrBy); return count; }catch(Exception e){ success = false; pool.returnBrokenResource(jedis); log.error("redis incr failed params:"); log.error("[counter:{}, incrBy:{}, defaultValue:{}]", new Object[]{counter, incrBy, defaultValue}); log.error("redis incr failed details:", e); throw new RuntimeException(e); }finally{ if(success){ pool.returnResource(jedis); } } } public long decrementAndGet(String counter, long decrBy, long defaultValue) { Jedis jedis = null; boolean success = true; try{ jedis = pool.getResource(); long count = jedis.decrBy(counter, decrBy); return count; }catch(Exception e){ success = false; pool.returnBrokenResource(jedis); log.error("redis decr failed params:"); log.error("[counter:{}, incrBy:{}, defaultValue:{}]", new Object[]{counter, decrBy, defaultValue}); log.error("redis decr failed details:", e); throw new RuntimeException(e); }finally{ if(success){ pool.returnResource(jedis); } } } public void shutdown() { try{ pool.destroy(); }catch(Exception e){ log.error("failed to shutdown redis client.", e); } } }还可以添加其他的缓存实现,然后在缓存工厂类里面同步加上创建方式就可以了
5. spring中配置缓存工厂实体bean的生成
<bean id="cacheManager" class="com.lutongnet.game.apiserver.cache.CacheManagerFactoryBean" destroy-method="shutdown"> <property name="provinder" value="${cache.provinder}"></property> <property name="addresses" value="${cache.addresses}"></property> <property name="poolsize" value="${cache.poolsize}"></property> </bean>
这样在其他地方就可以通过cacheManager这个实体bean去使用缓存的功能了
相关文章推荐
- Mutex::AutoLock
- SharePoint需要开启的网站集功能
- linq中的contains条件
- UITextView根据内容适应大小
- SDCC 2015架构专场札记:一线互联网公司的架构实践
- 第十周项目2-二叉树遍历的递归算法
- 查看凭证更改记录的三种方式
- 面试时,请勿提以下的问题!
- 第十二周 利用遍历思想求解图问题(经过顶点的所有简单路径)
- 什么是C++虚函数、虚函数的作用和使用方法
- 轻松学习JavaScript三:JavaScript与HTML的结合
- 查看office版本
- OpenCV 如何保存图片
- Spriing mvc上传多文件
- 第十二周项目1 图基本算法库
- wikioi 1002 旁路
- 点击和焦点事件
- poj 1178 Camelot 枚举
- java修改图片大小(留作备用)
- 不要让一个人随便进入你的世界,也不要拼命尝试进入一个人的世界