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狀態。