转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48446957
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实现
* @author liuyazhuang
*/
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" />
<!-- 配置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整合就完成了,spring的缓存还提供了很多的注解@Cachable,@cachePut.....,这里不多说了。