Memcached之——Memcached与Spring提供的cache接口整合

来源:互联网 发布:知我药妆网假货多吗 编辑:程序博客网 时间:2024/06/06 01:16

Spring 从3.x就提供了cache接口,spring默认实现的缓存是ehcache,spring的cache接口:

public interface Cache {String getName();Object getNativeCache();ValueWrapper get(Object key);<T> T get(Object key, Class<T> type);void put(Object key, Object value);void evict(Object key);void clear();interface ValueWrapper {Object get();}}

从spring的cache接口,我们可以看出spring的cache模型就是在内存中画一片内存区域出来,为这盘内存指定名称,在这盘内存区域中以key-value的方式存放数据,画个图来说明cache的存取方式,用户和部门的缓存,名称分别为DepartCache和UserCache

1. 要使用spring的cache,首先要实现cacheManager, 可以参考spring对ehcache的实现,整合memcached的代码如下:
/** * Spring Cache整合Memcached实现  */public class MemcachedCacheManager extends AbstractTransactionSupportingCacheManager {private ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();private Map<String, Integer> expireMap = new HashMap<String, Integer>();   //缓存的时间private MemcachedClient memcachedClient;   //xmemcached的客户端public MemcachedCacheManager() {}@Overrideprotected Collection<? extends Cache> loadCaches() {Collection<Cache> values = cacheMap.values();return values;}@Overridepublic Cache getCache(String name) {Cache cache = cacheMap.get(name);if (cache == null) {Integer expire = expireMap.get(name);if (expire == null) {expire = 0;expireMap.put(name, expire);}cache = new MemcachedCache(name, expire.intValue(), memcachedClient);cacheMap.put(name, cache);}return cache;}public void setMemcachedClient(MemcachedClient memcachedClient) {this.memcachedClient = memcachedClient;}public void setConfigMap(Map<String, Integer> configMap) {this.expireMap = configMap;}}

2. 接着看下MemcachedCache的实现,主要实现spring的cache接口

public class MemcachedCache implements Cache {private final String name;private final MemCache memCache;public MemcachedCache(String name, int expire, MemcachedClient memcachedClient) {this.name = name;this.memCache = new MemCache(name, expire, memcachedClient);}@Overridepublic void clear() {memCache.clear();}@Overridepublic void evict(Object key) {memCache.delete(key.toString());}@Overridepublic ValueWrapper get(Object key) {ValueWrapper wrapper = null;Object value = memCache.get(key.toString());if (value != null) {wrapper = new SimpleValueWrapper(value);}return wrapper;}@Overridepublic String getName() {return this.name;}@Overridepublic MemCache getNativeCache() {return this.memCache;}@Overridepublic void put(Object key, Object value) {memCache.put(key.toString(), value);}@Override@SuppressWarnings("unchecked")public <T> T get(Object key, Class<T> type) {Object cacheValue = this.memCache.get(key.toString());Object value = (cacheValue != null ? cacheValue : null);if (type != null && !type.isInstance(value)) {throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);}return (T) value;}}

3. spring提供的这套缓存api其实就是底层缓存框架与应用程序之间的中间层转换, 这里还有一个类就是MemCache,这个类主要是对应memcached缓存的模型,spring的缓存只是提供了一套api,具体的实现要根据底层使用的什么缓存框架:

MemCache.java

public class MemCache {private static Logger log = LoggerFactory.getLogger(MemCache.class);private Set<String> keySet = new HashSet<String>();private final String name;private final int expire;private final MemcachedClient memcachedClient;public MemCache(String name, int expire, MemcachedClient memcachedClient) {this.name = name;this.expire = expire;this.memcachedClient = memcachedClient;}public Object get(String key) {Object value = null;try {key = this.getKey(key);value = memcachedClient.get(key);} catch (TimeoutException e) {log.warn("获取 Memcached 缓存超时", e);} catch (InterruptedException e) {log.warn("获取 Memcached 缓存被中断", e);} catch (MemcachedException e) {log.warn("获取 Memcached 缓存错误", e);}return value;}public void put(String key, Object value) {if (value == null)return;try {key = this.getKey(key);memcachedClient.setWithNoReply(key, expire, value);keySet.add(key);} catch (InterruptedException e) {log.warn("更新 Memcached 缓存被中断", e);} catch (MemcachedException e) {log.warn("更新 Memcached 缓存错误", e);}}public void clear() {for (String key : keySet) {try {memcachedClient.deleteWithNoReply(this.getKey(key));} catch (InterruptedException e) {log.warn("删除 Memcached 缓存被中断", e);} catch (MemcachedException e) {log.warn("删除 Memcached 缓存错误", e);}}}public void delete(String key) {try {key = this.getKey(key);memcachedClient.deleteWithNoReply(key);} catch (InterruptedException e) {log.warn("删除 Memcached 缓存被中断", e);} catch (MemcachedException e) {log.warn("删除 Memcached 缓存错误", e);}}private String getKey(String key) {return name + "_" + key;}}

4. 在spring的配置文件中使用MemcachedCacheManager

<!-- 开启缓存 --><cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" /><!-- 配置memcached的缓存服务器 --><bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">   <constructor-arg><list><bean class="java.net.InetSocketAddress"><constructor-arg value="localhost" /><constructor-arg value="11211" /></bean></list></constructor-arg></bean><bean id="memcachedClient" factory-bean="memcachedClientBuilder" factory-method="build" destroy-method="shutdown" /><bean id="cacheManager" class="com.hqhop.framework.common.cache.memcached.MemcachedCacheManager"><property name="memcachedClient" ref="memcachedClient" /><!-- 配置缓存时间 --><property name="configMap">              <map>                  <!-- key缓存对象名称   value缓存过期时间 -->                <entry key="typeList" value="3600" />               </map>          </property>  </bean>

5. 到此为止,spring和memcached整合就完成了


原文出处:http://blog.csdn.net/l1028386804/article/details/48446957

0 0