Memcached之——整合Spring完整示例

来源:互联网 发布:软件行业平均毛利率 编辑:程序博客网 时间:2024/06/05 00:44
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48464111

在前面的几篇博文中,我们记录了Memcached整合Spring的一些方法,现在我们就基于这些方法实现一个Memcached整合Spring的完整示例,好了不多说了,我们直接上代码吧。

一、配置

1、MemcachedCacheManager

package com.cdsmartlink.framework.cache.memcached;import java.util.Collection;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import org.springframework.cache.Cache;import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;import com.danga.MemCached.MemCachedClient;/** * Spring Cache整合Memcached实现  * @author liuyazhuang */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;   //memcached的客户端public MemcachedCacheManager() {}@Overrideprotected Collection<? extends Cache> loadCaches() {Collection<Cache> values = cacheMap.values();return values;}@Overridepublic 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

package com.cdsmartlink.framework.cache.memcached;import org.springframework.cache.Cache;import org.springframework.cache.support.SimpleValueWrapper;import com.danga.MemCached.MemCachedClient;/** * MemcachedCache的实现,主要实现spring的cache接口 * @author liuyazhuang * */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);}@Overridepublic void clear() {memCache.clear();}@Overridepublic void evict(Object key) {memCache.delete(key.toString());}@Overridepublic ValueWrapper get(Object key) {ValueWrapper wrapper = null;Object value = memCache.get(key.toString());if (value != null) {wrapper = new SimpleValueWrapper(value);}return wrapper;}@Overridepublic String getName() {return this.name;}@Overridepublic MemCache getNativeCache() {return this.memCache;}@Overridepublic 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;}}

3、MemCache

package com.cdsmartlink.framework.cache.memcached;import java.util.HashSet;import java.util.Set;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.danga.MemCached.MemCachedClient;/** * Memcached的封装类 * @author liuyazhuang * */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 (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, value, expire);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;}}

4、applicationContext-memcached.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: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-3.0.xsd http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">      <!-- 扫描项目包的根路径 -->    <context:component-scan base-package="com.cdsmartlink" />    <context:component-scan base-package="com.cdsmartlink.utils.dao.base.impl"/>     <!-- ===================================  配置Memcached =============================== -->  <!-- 开启缓存 -->     <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" />      <!-- 导入外部properties -->    <context:property-placeholder location="classpath:memcached.properties"/>      <bean id="memcachedPool" class="com.danga.MemCached.SockIOPool"factory-method="getInstance" init-method="initialize" destroy-method="shutDown">   <constructor-arg><value>neeaMemcachedPool</value></constructor-arg><property name="servers"><list><value>${memcache.server}</value></list></property><property name="initConn"><value>${memcache.initConn}</value></property><property name="minConn"><value>${memcache.minConn}</value></property><property name="maxConn"><value>${memcache.maxConn}</value></property><property name="maintSleep"><value>${memcache.maintSleep}</value></property><property name="nagle"><value>${memcache.nagle}</value></property><property name="socketTO"><value>${memcache.socketTO}</value></property></bean><!-- 配置MemcachedClient --><bean id="memcachedClient" class="com.danga.MemCached.MemCachedClient"><constructor-arg><value>neeaMemcachedPool</value></constructor-arg></bean><!-- 配置缓存管理 --><bean id="cacheManager" class="com.cdsmartlink.framework.cache.memcached.MemcachedCacheManager"><property name="memcachedClient" ref="memcachedClient"/><!-- 配置缓存时间 --> <property name="configMap"> <map>  <!-- key缓存对象名称   value缓存过期时间 -->   <entry key="systemCache" value="3600"/> </map></property></bean> <!-- 导入调度任务 --> <!-- <import resource="spring-quartz.xml" /> --></beans>

5、memcached.properties

#Memcached基本配置memcache.server=192.168.254.120:12000memcache.initConn=20  memcache.minConn=10  memcache.maxConn=50  memcache.maintSleep=3000  memcache.nagle=false  memcache.socketTO=3000 

6、web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  <display-name>Smartlink</display-name>    <!-- 配置spring监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener> <!-- 配置初始化监听 -->    <listener>        <listener-class>com.cdsmartlink.utils.listener.WebServerStartListener</listener-class>    </listener><!-- 加载配置文件路径 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:applicationContext*.xml</param-value></context-param><!-- springmvc配置 --><servlet><servlet-name>smartlink</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>smartlink</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置OpenSessionInView --><filter>        <filter-name>hibernateFilter</filter-name>        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>        <!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->        <init-param>            <param-name>singleSession</param-name>            <param-value>true</param-value>        </init-param>    </filter><filter-mapping><filter-name>hibernateFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping><!-- 字符编码过滤器 -->    <filter>        <filter-name>CharacterEncodingFilter</filter-name>        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>        <init-param>            <param-name>encoding</param-name>            <param-value>UTF-8</param-value>        </init-param>        <init-param>            <param-name>forceEncoding</param-name>            <param-value>true</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>CharacterEncodingFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>       <welcome-file-list>    <welcome-file>index.html</welcome-file>    <welcome-file>index.htm</welcome-file>    <welcome-file>index.jsp</welcome-file>    <welcome-file>default.html</welcome-file>    <welcome-file>default.htm</welcome-file>    <welcome-file>default.jsp</welcome-file>  </welcome-file-list>     <error-page>        <error-code>404</error-code>        <location>/static/html/page_404/404.html</location>    </error-page></web-app>

二、使用示例

1、CacheBaseService

package com.cdsmartlink.utils.service;import java.io.Serializable;/** * 带有缓存的service * @author liuyazhuang * * @param <T> */public interface CacheBaseService<T> extends SinglePKBaseService<T>{T get(Serializable id);void save(T[] entity) ;void save(T entity) ;Serializable saveObj(T entity);void update(T entity) ;void delete(T entity) ;public int delete(Serializable id) ;public void delete(Serializable... id) ;}

2、CacheBaseServiceImpl

package com.cdsmartlink.utils.service.impl;import java.io.Serializable;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import com.cdsmartlink.utils.service.CacheBaseService;public abstract class CacheBaseServiceImpl<T> extends SinglePKBaseServiceImpl<T> implements CacheBaseService<T>{@Override@CachePut(value="systemCache")public T get(Serializable id){return super.get(id);}@Override@CacheEvict(value="systemCache", allEntries = true, beforeInvocation = true)public void save(T[] entity) { super.save(entity);}@Override@CacheEvict(value="systemCache", allEntries = true, beforeInvocation = true)public void save(T entity){super.save(entity);}@Override@CacheEvict(value="systemCache", allEntries = true, beforeInvocation = true)public Serializable saveObj(T entity){return super.saveObj(entity);}@Override@CacheEvict(value="systemCache", allEntries = true, beforeInvocation = true)public void update(T entity){super.update(entity);}@Override@CacheEvict(value="systemCache", allEntries = true, beforeInvocation = true)public void delete(T entity){super.delete(entity);}@Override@CacheEvict(value="systemCache", beforeInvocation = true)public int delete(Serializable id){return super.delete(id);}@Override@CacheEvict(value="systemCache", allEntries = true, beforeInvocation = true)public void delete(Serializable... id){super.delete(id);}}

3、StoreAdvertmentService

package com.cdsmartlink.system.store.service;import java.util.List;import com.cdsmartlink.system.store.entity.StoreAdvertment;import com.cdsmartlink.utils.service.CacheBaseService;/** * 商家广告service * @author liuyazhuang * */public interface StoreAdvertmentService extends CacheBaseService<StoreAdvertment> {/** * 缓存key的前缀 */String STORE_AD = "store_ad_";/** * 获取广告图 * @param storeId * @param type * @param limit * @return */List<StoreAdvertment> getStoreAdvertments(Long storeId, Integer type, int limit);}

4、StoreAdvertmentServiceImpl

package com.cdsmartlink.system.store.service.impl;import java.util.List;import javax.annotation.Resource;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import com.cdsmartlink.system.store.dao.StoreAdvertmentDao;import com.cdsmartlink.system.store.entity.StoreAdvertment;import com.cdsmartlink.system.store.service.StoreAdvertmentService;import com.cdsmartlink.utils.dao.QueryMode;import com.cdsmartlink.utils.dao.QueryParse;import com.cdsmartlink.utils.dao.base.BaseDao;import com.cdsmartlink.utils.service.impl.CacheBaseServiceImpl;@Servicepublic class StoreAdvertmentServiceImpl extends CacheBaseServiceImpl<StoreAdvertment> implementsStoreAdvertmentService {@Resourceprivate StoreAdvertmentDao storeAdvertmentDao;@Overrideprotected BaseDao<StoreAdvertment> getDao() {return storeAdvertmentDao;}@Overrideprotected void setQueryParse(QueryParse<StoreAdvertment> qp,QueryMode queryMode) {}@Override@Cacheable(value=SYSTEM_CACHE, key="'store_ad_'+ #storeId")//store_ad_为key的自定义字符串前缀,这个前缀可以根据具体业务设定,以免和其他缓存数据冲突,注意,这个字符串前缀要用单引号''括起来,否则会报错public List<StoreAdvertment> getStoreAdvertments(Long storeId, Integer type, int limit) {return storeAdvertmentDao.getStoreAdvertments(storeId, type, limit);}}

2 1