使用memcahed的客户端xmemcached实现Cache、CacheManager接口。
一、添加jar依赖
<dependency> <groupId>com.googlecode.xmemcached</groupId> <artifactId>xmemcached</artifactId> <version>2.0.0</version> </dependency>二、实现Cache接口
package org.springframework.cache.demo.memchache; import java.util.concurrent.TimeoutException; import net.rubyeye.xmemcached.MemcachedClient; import net.rubyeye.xmemcached.exception.MemcachedException; import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; public class MemcachedCache1 implements Cache { private MemcachedClient memcachedClient; public MemcachedClient getMemcachedClient() { return memcachedClient; } public void setMemcachedClient(MemcachedClient memcachedClient) { this.memcachedClient = memcachedClient; } @Override public String getName() { return memcachedClient.getName(); } @Override public Object getNativeCache() { return memcachedClient; } @Override public ValueWrapper get(Object key) { Object object = null; try { object = memcachedClient.get((String)key); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (MemcachedException e) { e.printStackTrace(); } return (object != null ? new SimpleValueWrapper(object) : null); } @SuppressWarnings("unchecked") @Override public <T> T get(Object key, Class<T> type) { Object object = null; try { object = memcachedClient.get((String)key); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (MemcachedException e) { e.printStackTrace(); } return (T)object; } @Override public void put(Object key, Object value) { try { memcachedClient.set((String) key, 86400, value); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (MemcachedException e) { e.printStackTrace(); } } @Override public ValueWrapper putIfAbsent(Object key, Object value) { put(key, value); return new SimpleValueWrapper(value); } @Override public void evict(Object key) { try { memcachedClient.delete((String)key); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (MemcachedException e) { e.printStackTrace(); } } @Override public void clear() { try { memcachedClient.flushAll(); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (MemcachedException e) { e.printStackTrace(); } } }三、实现 CacheManager
package org.springframework.cache.demo.memchache; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import net.rubyeye.xmemcached.MemcachedClient; import org.springframework.cache.Cache; import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager; 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; } }四、spring配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 --> <cache:annotation-driven cache-manager="cacheManager"/> <bean id="userService" class="org.springframework.cache.demo.UserService" /> <!-- spring自己的换管理器,这里定义了两个缓存位置名称 ,既注解中的value --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.demo.memchache.MemcachedCache1"> <property name="memcachedClient" ref="memcachedClient" /> </bean> </set> </property> </bean> <!-- 配置memcached的缓存服务器 --> <bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder"> <constructor-arg> <list> <bean class="java.net.InetSocketAddress"> <constructor-arg value="192.168.1.90" /> <constructor-arg value="11211" /> </bean> </list> </constructor-arg> <property name="name" value="userCache"/> </bean> <bean id="memcachedClient" factory-bean="memcachedClientBuilder" factory-method="build" destroy-method="shutdown" /> </beans>另外一种实现方式,可以采用simple-spring-memcached实现,依赖jar包:
<dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>simple-spring-memcached</artifactId> <version>3.5.0</version> </dependency> <dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>xmemcached-provider</artifactId> <version>3.5.0</version> </dependency>基于 xmemcached的spring集成。
也需要实现Cache接口:
package org.springframework.cache.demo.memchache; import java.util.concurrent.TimeoutException; import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; import com.google.code.ssm.api.format.SerializationType; import com.google.code.ssm.providers.CacheException; public class MemcachedCache2 implements Cache { private com.google.code.ssm.Cache cache; public com.google.code.ssm.Cache getCache() { return cache; } public void setCache(com.google.code.ssm.Cache cache) { this.cache = cache; } @Override public String getName() { return this.cache.getName(); } @Override public Object getNativeCache() { return this.cache; } @Override public ValueWrapper get(Object key) { Object object = null; try { object = this.cache.get((String)key, SerializationType.JAVA); } catch (TimeoutException e) { e.printStackTrace(); } catch (CacheException e) { e.printStackTrace(); } return (object != null ? new SimpleValueWrapper(object) : null); } @SuppressWarnings("unchecked") @Override public <T> T get(Object key, Class<T> type) { try { return (T)this.cache.get((String)key, SerializationType.JAVA); } catch (TimeoutException e) { e.printStackTrace(); } catch (CacheException e) { e.printStackTrace(); } return null; } @Override public void put(Object key, Object value) { try { this.cache.set((String)key, 86400, value, SerializationType.JAVA); } catch (TimeoutException e) { e.printStackTrace(); } catch (CacheException e) { e.printStackTrace(); } } @Override public ValueWrapper putIfAbsent(Object key, Object value) { put(key, value); return new SimpleValueWrapper(value); } @Override public void evict(Object key) { try { this.cache.delete((String)key); } catch (TimeoutException e) { e.printStackTrace(); } catch (CacheException e) { e.printStackTrace(); } } @Override public void clear() { try { this.cache.flush(); } catch (TimeoutException e) { e.printStackTrace(); } catch (CacheException e) { e.printStackTrace(); } } }这里就不实现CacheManager接口使用org.springframework.cache.support.SimpleCacheManager配置:
<?xml version='1.0' encoding='UTF-8'?> <beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:context='http://www.springframework.org/schema/context' xmlns:c='http://www.springframework.org/schema/c' xmlns:p='http://www.springframework.org/schema/p' xmlns:cache='http://www.springframework.org/schema/cache' xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=' http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd '> <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 --> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="userService" class="org.springframework.cache.demo.UserService" /> <!-- spring自己的换管理器,这里定义了两个缓存位置名称 ,既注解中的value --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.demo.memchache.MemcachedCache2"> <property name="cache" ref="memcachedCacheClient" /> </bean> </set> </property> </bean> <!-- memcached client defaultCache --> <bean name="memcachedCacheClient" class="com.google.code.ssm.CacheFactory"> <property name="cacheClientFactory"> <bean class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" /> </property> <property name="addressProvider"> <bean class="com.google.code.ssm.config.DefaultAddressProvider"> <property name="address" value="192.168.1.90:11211" /> </bean> </property> <property name="configuration"> <bean class="com.google.code.ssm.providers.CacheConfiguration"> <property name="consistentHashing" value="true" /> </bean> </property> <property name="cacheName" value="userCache" /> </bean> </beans>
参考文章:
1.Spring中@Cacheable的用法
2.Spring集成memcached的详细介绍