您的位置:首页 > 数据库 > Memcache

spring缓存集成memcache

2014-11-05 21:39 351 查看
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这个,代码如下:

[java]
view plaincopyprint?

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; 
  } 
     


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

[java]
view plaincopyprint?

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); 
        } 
      } 
    } 
     
  } 
    


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:

[html]
view plaincopyprint?

<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> 

<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状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: