第一步: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;
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
@Override
public 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
// @PostConstruct
public 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
// @PreDestroy
public 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;
//@Component
public 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);
}
}
}