`
半糖主义
  • 浏览: 21288 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

XMemcached与Spring3.2缓存框架集成

 
阅读更多

从Spring3.1开始,增加了抽像缓存框架,利用Spring3.1提供的注释,可以很方便的使用缓存,Spring官方给出基于Map和EHCache的实现,正好最近在用Memcached,参考了EHCacheCacheManager的源码,写了一个基于XMemcached的MemcachedCacheManager。

直接上代码(注:只支持Spring3.2以上版本)

 

1、MemcachedCacheManager.java

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;

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

 

public class MemcachedCache implements Cache
{
	private final String name;
	private final MemcachedClient memcachedClient;
	private final MemCache memCache;
	
	public MemcachedCache(String name, int expire, MemcachedClient memcachedClient)
	{
		this.name = name;
		this.memcachedClient = memcachedClient; 
		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 MemcachedClient getNativeCache()
	{
		return this.memcachedClient;
	}

	@Override
	public void put(Object key, Object value)
	{
		memCache.put(key.toString(), value);
	}
}

 3、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、配置文件 

<?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:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/cache
		http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"
		default-autowire="byName">
	
	<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>
		<property name="connectionPoolSize" value="5"/>
		<property name="commandFactory">
			<bean class="net.rubyeye.xmemcached.command.BinaryCommandFactory"/>
		</property>
		<property name="transcoder">
			<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
		</property>
	</bean>
	
	<bean id="memcachedClient" factory-bean="memcachedClientBuilder" factory-method="build" destroy-method="shutdown"/>
	
	<bean id="cacheManager" class="xxx.MemcachedCacheManager">
		<property name="memcachedClient" ref="memcachedClient" />
		<property name="configMap">
			<map>
			    <!-- key:@Cacheable、@CachePut、@CacheEvict等的name属性。value:缓存过期时间(单位:秒),默认值:0 -->
				<entry key="typeList" value="3600" />
			</map>
		</property>
	</bean>
	
	<cache:annotation-driven cache-manager="cacheManager"/>
	
</beans>

 至于如何使用Spring的@Cachable,google上一大堆,我就不再重复了。

分享到:
评论
6 楼 hahashuxue 2015-03-16  
configMap是什么memcachedManager里面也没有 运行报错
5 楼 yellowatumn 2014-12-09  
<property name="configMap"> 
            <map> 
                <!-- key:@Cacheable、@CachePut、@CacheEvict等的name属性。value:缓存过期时间(单位:秒),默认值:0 --> 
                <entry key="typeList" value="3600" /> 
            </map> 
        </property>
个人觉的这一段配置可以不要
4 楼 junxu1206 2013-09-03  
请问下楼主这个是什么意思
<property name="configMap"> 
            <map> 
                <!-- key:@Cacheable、@CachePut、@CacheEvict等的name属性。value:缓存过期时间(单位:秒),默认值:0 --> 
                <entry key="typeList" value="3600" /> 
            </map> 
        </property>
这个configMap哪儿定义了,还有关于 @Cacheable这样有个value的值是在哪儿获取的或者怎么设置的,可能我不太明白这个,如果有时间看到了谢谢解答一下,先谢
3 楼 半糖主义 2013-08-23  
ufohjl 写道
我觉得楼主对AbstractTransactionSupportingCacheManager的理解有点偏差

Spring自带的EhCacheManager也这样写
2 楼 ufohjl 2013-08-03  
我觉得楼主对AbstractTransactionSupportingCacheManager的理解有点偏差
1 楼 peter_wwhe 2013-07-18  

相关推荐

Global site tag (gtag.js) - Google Analytics