转自:http://tom-seed.iteye.com/blog/2104416
需要注意的是扩展支持注解需要Spring AOP的支持,需要导入相应的jar包:
1.aopalliance-1.0.jar
2.aopalliance-alpha1.jar
3.slf4j-api-1.7.5.jar
其中slf4j-api-1.7.5.jar提供的是日志的接口规范,如果工程目录下使用的是log4j,则slf4j-api-1.7.5.jar会绑定调用log4j.jar。
具体说明可以访问http://blog.csdn.net/tengdazhang770960436/article/details/18006127。
从头开始进行配置,步骤如下:
1.添加xmemcache.jar包至工程中;
- aopalliance-1.0.jar
- aopalliance-alpha1.jar
- slf4j-api-1.7.5.jar
- xmemcached-1.3.8.jar
2.在web.xml文件中添加配置
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- /WEB-INF/conf/spring/*-beans.xml
- </param-value>
- </context-param>
3.在属性文件中添加如下配置:
- #memcache配置
- memcache.ip=127.0.0.1
- memcache.port=11211
- memcache.pool.size=5
4.在/WEB-INF/conf/spring/目录下添加配置文件memcache-beans.xml
- <?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="${memcache.ip}" />
- <constructor-arg value="${memcache.port}" />
- </bean>
- </list>
- </constructor-arg>
- <property name="connectionPoolSize" value="${memcache.pool.size}" />
- <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="com.iaccount.framework.cache.memcache.MemcachedCacheManager">
- <property name="memcachedClient" ref="memcachedClient" />
- <property name="configMap">
- <map>
- <!-- key:@Cacheable、@CachePut、@CacheEvict等的value属性。value:缓存过期时间(单位:秒),默认值:0 -->
- <entry key="defaultCache" value="0" /><!-- 默认缓存区 不过期 -->
- <entry key="inTimeCache" value="3600" /><!-- 实时缓存区 一小时过期 -->
- </map>
- </property>
- </bean>
- <cache:annotation-driven cache-manager="cacheManager" />
- </beans>
5.参考了EHCacheCacheManager的源码,写了一个基于XMemcached的MemcachedCacheManager
a.memcache缓存连接类 MemCache.java
- import java.util.HashSet;
- import java.util.Set;
- import java.util.concurrent.TimeoutException;
- import net.rubyeye.xmemcached.MemcachedClient;
- import net.rubyeye.xmemcached.exception.MemcachedException;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- 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;
- }
- }
b.缓存类 MemcachedCache.java
- import net.rubyeye.xmemcached.MemcachedClient;
- import org.springframework.cache.Cache;
- import org.springframework.cache.support.SimpleValueWrapper;
- 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);
- }
- }
c.缓存管理类 MemcachedCacheManager.java
- 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;
- 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;
- }
- }
6.数据操作类
- @Cacheable(value="defaultCache")
- public List<FmSupplier> getEnableSuppliers(){
- FmSupplierQuery query = new FmSupplierQuery();
- query.setIsDeleted(YesNoType.NO.getCode());
- query.setSupplierStatus(SupplierStatus.ENABLE.getCode());
- return fmSupplierMapper.selectListByQuery(query);
- }
- @Cacheable(value="defaultCache", key="#id")
- public FmSupplier selectByPrimaryKey(Long id){
- return fmSupplierMapper.selectByPrimaryKey(id);
- }
1.在缓存区defaultCache中获取数据,第一次请求时无数据,则会从数据库中获取并放至缓存中;
2.第二次请求时则直接从缓存中获取;