第一步:IMemcachedManager 接口开发:
package com.yum.services.common.cache;/** * * @author gejk * * 对于memcached还有一些指令也可以放到此接口中 * */public interface IMemcachedManager { /** * 取出指定KEY的缓存对象 * * @param key * @return * @throws MemcachedException */ Object get(String key) throws MemcachedException; /** * 如果缓存中没有此KEY 则增加进去。如果有,则还保留原始值 * * @param key * @param value * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean add(String key, Object value) throws MemcachedException; /** * 功能同add(key value),不过加上缓存的时效性。单位为豪秒 * * @param key * @param value * @param expireInSeconds * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean add(String key, Object value, long expireInSeconds) throws MemcachedException; /** * 删除指定KEY的缓存对象 * * @param key * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean delete(String key) throws MemcachedException; /** * 替换指定KEY的缓存对象 * * @param key * @param value * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean replace(String key, Object value) throws MemcachedException; /** * 功能同replace(key vale) 加缓存时效 单位为豪秒 * * @param key * @param value * @param expireInSeconds * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean replace(String key, Object value, long expireInSeconds) throws MemcachedException; /** * 设置指定KEY的缓存对象 * * @param key * @param value * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean set(String key, Object value) throws MemcachedException; /** * 设置同set(key vale) 加缓存时效 单位为豪秒 * * @param key * @param value * @param expireInSeconds * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean set(String key, Object value, long expireInSeconds) throws MemcachedException; /** * 清空所有缓存 * * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean flushAll() throws MemcachedException; /** * 清空指定的缓存对象 * * @param arg0 * @return true 表示成功。 false表示失败 * @throws MemcachedException */ boolean flushAll(String[] arg0) throws MemcachedException; /** * 初始化方法 * @throws Exception */ void initialize() throws Exception; /** * 销毁 */ void destroy();}
第二步:MemcachedException异常类开发:
package com.yum.services.common.cache;public class MemcachedException extends Exception {/** * */private static final long serialVersionUID = -6280079694740536232L;public MemcachedException() {super();}public MemcachedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public MemcachedException(String message, Throwable cause) {super(message, cause);}public MemcachedException(String message) {super(message);}public MemcachedException(Throwable cause) {super(cause);}}
第三步:IMemcachedManager接口实现类XMemcachedManagerImpl开发:
package com.yum.services.common.cache;import java.io.IOException;import java.util.concurrent.TimeoutException;import net.rubyeye.xmemcached.MemcachedClient;import net.rubyeye.xmemcached.MemcachedClientBuilder;import net.rubyeye.xmemcached.XMemcachedClientBuilder;import net.rubyeye.xmemcached.exception.MemcachedException;import net.rubyeye.xmemcached.utils.AddrUtil;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * 使用xmemcached的客户端,用于解决某些情况下java-memcached-client非正常阻塞的情况 * @author 杨溪 * */public class XMemcachedManagerImpl implements IMemcachedManager {/** * xmemcache客户端最大只支持30天,这里使用29天 */private static final int INFINITE_EXPIRE_TIME = 29 * 24 * 3600;private static final Logger log = LoggerFactory.getLogger(XMemcachedManagerImpl.class);private MemcachedClientBuilder builder;private String servers;private int connSize;/** * memcache连接 * 如果未成功连接,为null */private MemcachedClient client = null;@Overridepublic Object get(String key) throws com.yum.services.common.cache.MemcachedException {try {return client.get(key);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean add(String key, Object value) throws com.yum.services.common.cache.MemcachedException {try {return client.add(key, INFINITE_EXPIRE_TIME, value);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean add(String key, Object value, long expireInSeconds)throws com.yum.services.common.cache.MemcachedException {try {return client.add(key, (int) expireInSeconds, value);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean delete(String key) throws com.yum.services.common.cache.MemcachedException {try {return client.delete(key);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean replace(String key, Object value) throws com.yum.services.common.cache.MemcachedException {try {return client.replace(key, INFINITE_EXPIRE_TIME, value);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean replace(String key, Object value, long expireInSeconds)throws com.yum.services.common.cache.MemcachedException {try {return client.replace(key, (int) expireInSeconds, value);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean set(String key, Object value) throws com.yum.services.common.cache.MemcachedException {try {return client.set(key, INFINITE_EXPIRE_TIME, value);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean set(String key, Object value, long expireInSeconds)throws com.yum.services.common.cache.MemcachedException {try {return client.set(key, (int) expireInSeconds, value);} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean flushAll() throws com.yum.services.common.cache.MemcachedException {try {client.flushAll();return true;} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Overridepublic boolean flushAll(String[] arg0) throws com.yum.services.common.cache.MemcachedException {try {client.flushAll();return true;} catch (TimeoutException | InterruptedException | MemcachedException e) {log.error("Memcached client error", e);throw new com.yum.services.common.cache.MemcachedException(e);}}@Override//@PostConstructpublic void initialize() {try {doInitialize();} catch (Exception e) {log.error("Failed to init memcache client", e);}}protected void doInitialize() throws IOException {builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(this.servers.replaceAll(",", " ")));//builder.setSessionLocator(new HAArrayMemcachedSessionLocator());builder.setConnectionPoolSize(this.connSize);try {client = this.builder.build();} catch (IOException e) {throw e;}}@Override//@PreDestroypublic void destroy() {try {if (client != null) {client.shutdown();client = null;}} catch (IOException e) {log.error("Failed to destroy memcached client", e);}}public void setServers(String servers) {this.servers = servers;}public void setConnSize(int connSize) {this.connSize = connSize;}}
第四步:CacheClient客户端开发:
package com.yum.services.common.cache;//@Componentpublic class CacheClient {// @Resource(name = "memcached")private IMemcachedManager memcached;public void add(String key, Object value) throws MemcachedException {this.memcached.add(key, value);}public void add(String key, Object value, long expireInSeconds) throws MemcachedException {this.memcached.add(key, value, expireInSeconds);}public void save(String key, Object value) throws MemcachedException {this.memcached.set(key, value);}public void save(String key, Object value, long expireInSeconds) throws MemcachedException {this.memcached.set(key, value, expireInSeconds);}public Object get(String key) throws MemcachedException {return memcached.get(key);}public void delete(String key) throws MemcachedException {memcached.delete(key);}public IMemcachedManager getMemcached() {return memcached;}public void setMemcached(IMemcachedManager memcached) {this.memcached = memcached;}}
第五步:memcached.properties开发:
memcached.servers=10.20.92.72:11211
第六步:Memcached与Spring集成:
<bean id="memcached" class="com.yum.services.common.cache.XMemcachedManagerImpl" init-method="initialize" destroy-method="destroy"><property name="servers" value="#{memcacheProperties['memcached.servers']}"></property><property name="connSize" value="#{memcacheProperties['memcached.initConn']}"></property></bean><bean id="cacheClient" class="com.yum.services.common.cache.CacheClient"><property name="memcached" ref="memcached"></property></bean>
第七步:实际应用开发:
package com.yum.services.promotion.persistence.kfc;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Calendar;import java.util.Collections;import java.util.Comparator;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.fasterxml.jackson.annotation.JsonIgnore;import com.yum.services.common.ServiceExceptionConstants;import com.yum.services.common.cache.CacheClient;import com.yum.services.common.cache.MemcachedException;import com.yum.services.common.utils.CollectionUtil;import com.yum.services.common.utils.StringUtils;import com.yum.services.order.domain.ICollectGoods;import com.yum.services.promotion.PromotionServiceException;import com.yum.services.promotion.domain.kfc.Holiday;import com.yum.services.promotion.domain.kfc.HolidayMap;import com.yum.services.promotion.domain.kfc.KFCICollectLevel;import com.yum.services.promotion.domain.kfc.KFCICouponCode;import com.yum.services.promotion.domain.kfc.KFCICustomerTagRel;import com.yum.services.promotion.domain.kfc.KFCIDayPart;import com.yum.services.promotion.domain.kfc.KFCIPromotion;import com.yum.services.promotion.domain.kfc.KFCIPromotionConstants;import com.yum.services.promotion.domain.kfc.KFCIPromotionRelation;import com.yum.services.promotion.domain.kfc.KFCPromotionItem;import com.yum.services.promotion.domain.kfc.MenuDisable;import com.yum.services.promotion.exception.PromotionException;import com.yum.services.promotion.services.kfc.ICouponHelper;import com.yum.services.promotion.services.kfc.impl.SimplePromotion;/** * 将所有的Mapper对象整合,Cache同步操作在此处实现。 * * @author 林杨 @date 2012-11-28 * @version 1.0 */@SuppressWarnings("unchecked")@Service("DomainMapper")public class DomainMapper2 implements ICouponMapper { @JsonIgnore protected Logger log = LoggerFactory.getLogger(DomainMapper.class); @Autowired private ICouponMapper couponMapper; @Resource(name = "cacheClient") private CacheClient memcached; @Override public List<Holiday> getHolidays(int year) { return couponMapper.getHolidays(year); } /** * 获取节假日列表 */ public HolidayMap getHolidayMap() { HolidayMap holidayMap = null; Object holiday = null; try { holiday = memcached.get(KFCIPromotionConstants.MEMCACHE_KEY_HOLIDAY); } catch (MemcachedException e) { log.warn("从memcached中获取HolidayMap失败!"); } if (null == holiday) { holiday = holidayMap = new HolidayMap(); Calendar cal = Calendar.getInstance(); int year = cal.get(Calendar.YEAR); List<Holiday> listHoliday = couponMapper.getHolidays(year); for (Holiday h : listHoliday) { holidayMap.addHoliday(h); } try { memcached.save(KFCIPromotionConstants.MEMCACHE_KEY_HOLIDAY, holidayMap, KFCIPromotionConstants.MEMCACHE_TIMEOUT_PRO); } catch (MemcachedException e) { log.warn("往memcached中设置HolidayMap失败!"); } } else { holidayMap = (HolidayMap) holiday; } return holidayMap; } /** * 使用反射获取数据 * * @param memcachekey 保存进memcache使用的key * @param queryMethodName 查询方法名 * @return 获取到的列表数据 */ public Object getData(String memcachekey, String queryMethodName) { Object obj = null; try { obj = memcached.get(memcachekey); } catch (Exception e) { log.warn("从memcached获取" + queryMethodName + "失败!"); } if (null == obj) { try { Class<?> c = ICouponMapper.class; Method m = c.getMethod(queryMethodName); obj = m.invoke(couponMapper); memcached.save(memcachekey, obj,KFCIPromotionConstants.MEMCACHE_TIMEOUT_PRO); } catch (Exception e) { log.warn("往memcached中设置" + queryMethodName + "失败"); } } return obj; } /** * 判断是否存在标记位 * * @return true为存在 */ public boolean isExistsFlag() { try { Object obj = memcached.get(KFCIPromotionConstants.MEMCACHE_KEY_FLAG); if (obj == null) { return false; } return true; } catch (MemcachedException e) { log.error("isExistsFlag error : ", e); return false; } } /** * 设置标记位 */ public void setFlag() { try { memcached.save(KFCIPromotionConstants.MEMCACHE_KEY_FLAG, "true",KFCIPromotionConstants.MEMCACHE_ENGINX_TIMEOUT); } catch (MemcachedException e) { log.error("setFlag error : ", e); } } /** * 清空缓存 * * @throws MemcachedException */ public void clearCache() { try { this.memcached.delete(KFCIPromotionConstants.MEMCACHE_KEY_FLAG); this.memcached.delete(KFCIPromotionConstants.MEMCACHE_KEY_HOLIDAY); } catch (MemcachedException e) { log.error("clearCache error : ", e); } }}