spring整合memcache配置

一 所需jar包

<dependency>
       <groupId>com.danga.MemCached</groupId>
       <artifactId>memcached-client</artifactId>
       <version>2.6.6</version>
 </dependency>
<!-- 及spring相关 jar包 -->dependency>
       <groupId>com.danga.MemCached</groupId>
       <artifactId>memcached-client</artifactId>
       <version>2.6.6</version>
 </dependency>
<!-- 及spring相关 jar包 -->

二 spring-memcached.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:p="http://www.springframework.org/schema/p"  
       xmlns:context="http://www.springframework.org/schema/context"  
       xmlns:aop="http://www.springframework.org/schema/aop"   
       xmlns:tx="http://www.springframework.org/schema/tx"  
       xmlns:mvc="http://www.springframework.org/schema/mvc"  
       xmlns:cache="http://www.springframework.org/schema/cache"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
                        http://www.springframework.org/schema/context   
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd  
                        http://www.springframework.org/schema/tx   
                        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd  
                        http://www.springframework.org/schema/aop   
                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
                        http://www.springframework.org/schema/mvc   
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd  
                        http://www.springframework.org/schema/cache   
                        http://www.springframework.org/schema/cache/spring-cache.xsd">  
    <!-- ===================================  配置Memcached =============================== -->  
    
    
     <!-- 开启缓存 -->    
   <cache:annotation-driven cache-manager="cacheManager"  />    
    
       <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="com.wutongyu.cache.memcache.MemcachedCacheManager">  
        <property name="memcachedClient" ref="memcachedClient"/>  
        <!-- 配置缓存时间 -->   
        <property name="configMap">  
             <map>  
                 <!-- key缓存对象名称   value缓存过期时间  表示存储一个月-->
                 <entry key="siemCache" value="0"/>
             </map>  
        </property>  
    </bean>  
</beans>    

三 缓存管理类 MemcachedCacheManager及相关

package com.wutongyu.cache.memcache;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
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.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;
    }
    
    /**
     * 通过memcachedClient更新缓存
     * @param key
     * @param value
     * @throws InterruptedException
     * @throws MemcachedException
     * @throws TimeoutException
     */
    public void put(String key,Object value) throws InterruptedException, MemcachedException, TimeoutException {
        this.memcachedClient.set(key,0,value);
    }
    /**
     * 通过memcachedClient获取缓存
     * @param key
     * @return
     * @throws InterruptedException
     * @throws MemcachedException
     * @throws TimeoutException
     */
    public Object get(String key) throws InterruptedException, MemcachedException, TimeoutException {
        return this.memcachedClient.get( key);
    }
    public void setMemcachedClient(MemcachedClient memcachedClient) {
        this.memcachedClient = memcachedClient;
        //关闭心跳
        memcachedClient.setEnableHeartBeat(false);
    }
    public void setConfigMap(Map<String, Integer> configMap) {
        this.expireMap = configMap;
    }
}
​
package com.wutongyu.cache.memcache;
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 MemCache memCache;
    public MemcachedCache(String name, int expire,MemcachedClient memcachedClient) {
        this.name = name;
        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 MemCache getNativeCache() {
        return this.memCache;
    }
    @Override
    public void put(Object key, Object value) {
        memCache.put(key.toString(), value);
    }
    @Override
    @SuppressWarnings("unchecked")
    public <T> T get(Object key, Class<T> type) {
        Object cacheValue = this.memCache.get(key.toString());
        Object value = (cacheValue != null ? cacheValue : null);
        if (type != null && !type.isInstance(value)) {
            throw new IllegalStateException("Cached value is not of required type [" + type.getName()+ "]: " + value);
        }
        return (T) value;
    }
    @Override
    public ValueWrapper putIfAbsent( Object key, Object value ) {
        // TODO Auto-generated method stub
        return null;
    }
}
​
package com.wutongyu.cache.memcache;
import java.util.HashSet;
import java.util.Set;
import net.rubyeye.xmemcached.MemcachedClient;
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,10000);  
        } catch (Exception e) {  
            log.warn("获取 Memcached 缓存超时", e);  
        }  
        return value;  
    }  
    public void put(String key, Object value) {  
        if (value == null)  
            return;  
        try {  
            key = this.getKey(key);  
            memcachedClient.set(key,expire, value,10000);  
            keySet.add(key);  
        }catch (Exception e) {  
            log.warn("更新 Memcached 缓存错误", e);  
        }  
    }  
    public void clear() {  
        for (String key : keySet) {  
            try {  
                memcachedClient.delete(this.getKey(key));  
            }catch (Exception e) {  
                log.warn("删除 Memcached 缓存错误", e);  
            }  
        }  
    }  
    public void delete(String key) {  
        try {  
            key = this.getKey(key);  
            memcachedClient.delete(key);  
        } catch (Exception e) {  
            log.warn("删除 Memcached 缓存被中断", e);  
        }  
    }  
    private String getKey(String key) {  
        return name + "_" + key;  
    }  
} com.wutongyu.cache.memcache;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
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.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;
    }
    
    /**
     * 通过memcachedClient更新缓存
     * @param key
     * @param value
     * @throws InterruptedException
     * @throws MemcachedException
     * @throws TimeoutException
     */
    public void put(String key,Object value) throws InterruptedException, MemcachedException, TimeoutException {
        this.memcachedClient.set(key,0,value);
    }
    /**
     * 通过memcachedClient获取缓存
     * @param key
     * @return
     * @throws InterruptedException
     * @throws MemcachedException
     * @throws TimeoutException
     */
    public Object get(String key) throws InterruptedException, MemcachedException, TimeoutException {
        return this.memcachedClient.get( key);
    }
    public void setMemcachedClient(MemcachedClient memcachedClient) {
        this.memcachedClient = memcachedClient;
        //关闭心跳
        memcachedClient.setEnableHeartBeat(false);
    }
    public void setConfigMap(Map<String, Integer> configMap) {
        this.expireMap = configMap;
    }
}
​
package com.wutongyu.cache.memcache;
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 MemCache memCache;
    public MemcachedCache(String name, int expire,MemcachedClient memcachedClient) {
        this.name = name;
        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 MemCache getNativeCache() {
        return this.memCache;
    }
    @Override
    public void put(Object key, Object value) {
        memCache.put(key.toString(), value);
    }
    @Override
    @SuppressWarnings("unchecked")
    public <T> T get(Object key, Class<T> type) {
        Object cacheValue = this.memCache.get(key.toString());
        Object value = (cacheValue != null ? cacheValue : null);
        if (type != null && !type.isInstance(value)) {
            throw new IllegalStateException("Cached value is not of required type [" + type.getName()+ "]: " + value);
        }
        return (T) value;
    }
    @Override
    public ValueWrapper putIfAbsent( Object key, Object value ) {
        // TODO Auto-generated method stub
        return null;
    }
}
​
package com.wutongyu.cache.memcache;
import java.util.HashSet;
import java.util.Set;
import net.rubyeye.xmemcached.MemcachedClient;
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,10000);  
        } catch (Exception e) {  
            log.warn("获取 Memcached 缓存超时", e);  
        }  
        return value;  
    }  
    public void put(String key, Object value) {  
        if (value == null)  
            return;  
        try {  
            key = this.getKey(key);  
            memcachedClient.set(key,expire, value,10000);  
            keySet.add(key);  
        }catch (Exception e) {  
            log.warn("更新 Memcached 缓存错误", e);  
        }  
    }  
    public void clear() {  
        for (String key : keySet) {  
            try {  
                memcachedClient.delete(this.getKey(key));  
            }catch (Exception e) {  
                log.warn("删除 Memcached 缓存错误", e);  
            }  
        }  
    }  
    public void delete(String key) {  
        try {  
            key = this.getKey(key);  
            memcachedClient.delete(key);  
        } catch (Exception e) {  
            log.warn("删除 Memcached 缓存被中断", e);  
        }  
    }  
    private String getKey(String key) {  
        return name + "_" + key;  
    }  
}

四 spring.xml 调用spring-memcached.xml 连接memcache

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:mvc="http://www.springframework.org/schema/mvc" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/cache 
        http://www.springframework.org/schema/cache/spring-cache.xsd"><!-- 引入属性文件 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
                <value>classpath:rabbitmq.properties</value>
            </list>
        </property>
    </bean>
    <import resource="spring-mybatis.xml" />
    <import resource="spring-security.xml" />
    <import resource="spring-memcached.xml" />
</beans> version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:mvc="http://www.springframework.org/schema/mvc" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/cache 
        http://www.springframework.org/schema/cache/spring-cache.xsd"><!-- 引入属性文件 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
                <value>classpath:rabbitmq.properties</value>
            </list>
        </property>
    </bean>
    <import resource="spring-mybatis.xml" />
    <import resource="spring-security.xml" />
    <import resource="spring-memcached.xml" />
</beans>

五 java使用方式

//key-value的方式插入缓存
@Override
@Cacheable( value = "siemCache", key = "'getStrategyInfoByLogSourceUuid_'+#logSourceUuid" )
public List<StrategyInfo> getStrategyInfoByLogSourceUuid(String logSourceUuid){
    List<StrategyInfo> strategyInfos=new ArrayList<>();
    List<StrategyLogSourceRel> strategyLogSourceRels=strategyLogSourceRelService.getStrategyLogSourceRelByLogSourceUuid(logSourceUuid);
    if(CollectionUtils.isNotEmpty(strategyLogSourceRels)){
        List<String> uuidList=new ArrayList<>();
        strategyLogSourceRels.forEach(strategyLogSourceRel->{
            uuidList.add(strategyLogSourceRel.getStrategyUuid());
        });
        strategyInfos = strategyInfodao.getStrategyInfoByUuidList(uuidList);
    }
    return strategyInfos;
}
//删除缓存
@Override
@CacheEvict( value = "siemCache", key = "'getStrategyInfoByLogSourceUuid_'+#logSourceUuid" )
public void deleteCache(String logSourceUuid){
​
}
@Override
@Cacheable( value = "siemCache", key = "'getStrategyInfoByLogSourceUuid_'+#logSourceUuid" )
public List<StrategyInfo> getStrategyInfoByLogSourceUuid(String logSourceUuid){
    List<StrategyInfo> strategyInfos=new ArrayList<>();
    List<StrategyLogSourceRel> strategyLogSourceRels=strategyLogSourceRelService.getStrategyLogSourceRelByLogSourceUuid(logSourceUuid);
    if(CollectionUtils.isNotEmpty(strategyLogSourceRels)){
        List<String> uuidList=new ArrayList<>();
        strategyLogSourceRels.forEach(strategyLogSourceRel->{
            uuidList.add(strategyLogSourceRel.getStrategyUuid());
        });
        strategyInfos = strategyInfodao.getStrategyInfoByUuidList(uuidList);
    }
    return strategyInfos;
}
//删除缓存
@Override
@CacheEvict( value = "siemCache", key = "'getStrategyInfoByLogSourceUuid_'+#logSourceUuid" )
public void deleteCache(String logSourceUuid){
​
}

注意:后台根据key值查看memcache缓存内容

(1)telnet进入11211端口: telnet 127.0.0.1 11211
(2)根据key找到对应的缓存: get key 
    示例:上面例子中 拼出的key值为 siemCache_getStrategyInfoByLogSourceUuid_32位uuid
          get siemCache_getStrategyInfoByLogSourceUuid_32位uuid
(3)列出所有的连接池信息: stats items
(4)通过如上连接池信息获取 key 的值,再根据具体的key值找到缓存: stats cachedump 7 0       1)telnet进入11211端口: telnet 127.0.0.1 11211
(2)根据key找到对应的缓存: get key 
    示例:上面例子中 拼出的key值为 siemCache_getStrategyInfoByLogSourceUuid_32位uuid
          get siemCache_getStrategyInfoByLogSourceUuid_32位uuid
(3)列出所有的连接池信息: stats items
(4)通过如上连接池信息获取 key 的值,再根据具体的key值找到缓存: stats cachedump 7 0       

猜你喜欢

转载自blog.csdn.net/wutongyuWxc/article/details/79299976