`
cloudtech
  • 浏览: 4611171 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

spring缓存集成memcache

 
阅读更多

spring3.1.0开始支持注解方式的缓存实现,非常方便,不过它目前只支持java内置的ConcurrentMap和ehcache这两种缓存方式,因为项目用到memcache,就想把memcache集成到spring内置的缓存中,使memcache也能用注解方式来调用。于是参考ehcache的集成方式,把memcache集成到项目中。spring把所有缓存都抽象为一个cache,相当于一个缓存集合,即spring缓存注解@Cacheable(value="xxx")中xxx对应的结果集合。首先我们要实现Cache这个接口,memcache的java客户端我们用的是com.danga.MemCached.MemCachedClient这个,代码如下:

public class MemcacheCache implements Cache {
  
  private MemCachedClient client;
  private String name;
  
  public MemcacheCache(){
    
  }
  
  public MemcacheCache(String name,MemCachedClient client) {
    Assert.notNull(client, "Memcache client must not be null");
    // TODO validate memcache "alive"
    this.client = client;
    this.name = name;
  }
  
  @Override
  @Cacheable(value="xxxx")
  public String getName() {
    return this.name;
  }
  
  @Override
  public Object getNativeCache() {
    return this.client;
  }
  
  @Override
  public ValueWrapper get(Object key) {
    Object value = this.client.get(objectToString(key));
    return (value != null ? new SimpleValueWrapper(value) : null);
  }
  
  @Override
  public void put(Object key, Object value) {
    this.client.set(objectToString(key), value);
    
  }
  
  @Override
  public void evict(Object key) {
    this.client.delete(objectToString(key));
    
  }
  
  @Override
  public void clear() {
    // TODO delete all data   
  }
  
  private static String objectToString(Object object) {
    if (object == null) {
      return null;
    } else if (object instanceof String) {
      return (String) object;
    } else {
      return object.toString();
    }
  }
  
  public void setClient(MemCachedClient client){
    this.client = client;
  }

  public MemCachedClient getClient() {
    return client;
  }

  public void setName(String name) {
    this.name = name;
  }
    
}


然后是要扩展AbstractCacheManager这个缓存管理抽象类,它主要负责生成和读取Cache,代码如下:

public class MemcacheCacheManager extends AbstractCacheManager {
  
  private Collection<Cache> caches;
  private MemCachedClient client = null;
  
  public MemcacheCacheManager() {

  }
  
  public MemcacheCacheManager(MemCachedClient client){
    setClient(client);
  }
  
  @Override
  protected Collection<? extends Cache> loadCaches() {    
    return this.caches;
  }
  
  public void setCaches(Collection<Cache> caches) {
    this.caches = caches;
  }
  
  public void setClient(MemCachedClient client) {
    this.client = client;
    updateCaches();
  }
  
  public Cache getCache(String name){
    checkState();
    
    Cache cache = super.getCache(name);
    if(cache == null){
      cache = new MemcacheCache(name, client);
      addCache(cache);
    }
    return cache;
  }
  
  private void checkState() {
    if(client == null){
      throw new IllegalStateException("MemcacheClient must not be null.");
    }
    //TODO check memcache state
    
  }

  private void updateCaches() {
    if(caches != null){
      for(Cache cache : caches){
        if(cache instanceof MemcacheCache){
          MemcacheCache memcacheCache = (MemcacheCache)cache;
          memcacheCache.setClient(client);
        }
      }
    }
    
  }
   
}

配置bean:

<bean id="cacheManager" class="com.youboy.cshop.utils.memcache.MemcacheCacheManager">
	<property name="client" value="memcachedClient"/>
	<property name="caches">
		<set>
			<bean class="com.youboy.cshop.utils.memcache.MemcacheCache">
				<property name="name" value="testCache"/>
				<property name="client" ref="memcachedClient"/>
			</bean>
		</set>
	</property>
</bean>


其中memcachedClient为你memcache的客户端,你可以配置多个MemcacheCache,配置完这里你就你就可以把@Cacheable(value="testCache")添加到方法那来缓存执行结果,这里value="testCache"的值必须和上面bean文件配置的一致,否则无法缓存。这只是做了个简单的集成,还有很多要完善的,比如连接时检查memcache状态。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics