当前位置: 代码迷 >> J2EE >> J2EE开发框架搭建(九) - memcached与spring提供的cache接口整合
  详细解决方案

J2EE开发框架搭建(九) - memcached与spring提供的cache接口整合

热度:313   发布时间:2016-04-17 23:40:46.0
J2EE开发框架搭建(9) - memcached与spring提供的cache接口整合

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的代码如下:

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() {	}	@Override	protected Collection<? extends Cache> loadCaches() {		Collection<Cache> values = cacheMap.values();		return values;	}	@Override	public 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);	}	@Override	public void clear() {		memCache.clear();	}	@Override	public void evict(Object key) {		memCache.delete(key.toString());	}	@Override	public ValueWrapper get(Object key) {		ValueWrapper wrapper = null;		Object value = memCache.get(key.toString());		if (value != null) {			wrapper = new SimpleValueWrapper(value);		}		return wrapper;	}	@Override	public String getName() {		return this.name;	}	@Override	public MemCache getNativeCache() {		return this.memCache;	}	@Override	public 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" />    <!-- 开启缓存 --><bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">   <!-- 配置memcached的缓存服务器 -->	<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>                <entry key="typeList" value="3600" /> <!-- key缓存对象名称   value缓存过期时间 -->           </map>        </property></bean>

?5. 到此为止,spring和memcached整合就完成了,spring的缓存还提供了很多的注解@Cachable,@cachePut.....

  相关解决方案