基于memcache的远程缓存工具类

基于memcache的远程缓存工具类如下:

温馨提示:此代码粘贴不可用,依赖于公司扩展的memcached包


先上文件包结构:

cache  --远程缓存
		checkutils --检查数据正确性
		hex  --一种对整形字符做转换加密的算法
		MemcachedServiceImpl --提供Memcached缓存实现
		NoneCacheServiceImpl --没有缓存的实现
		RemoteCacheService   --需要被实现的远程集中式缓存接口
		RemoteCacheUtils     --web存放远程缓存工具类
		testMain  --测试主类
		memcached.xml  --连接memcached的配置文件

1.测试主类:

public class testMain {

	public static void main(String[] args) {
		Student student=null;
		String key="fghjkltyui";
		LocalCacheUtils.init();
		
		if (!CheckUtils.isEmpty(RemoteCacheUtils.get(key))) {
			//有缓存数据
			student = (Student) RemoteCacheUtils.get(key);
			System.out.println(student.getName());
		}else {
			//没缓存数据,则student模拟数据库创建数据
			Student stu=new Student();
			stu.setAge(26);
			stu.setName("台湾");
			stu.setId("1");
			
			//数据库查到数据后,添加缓存
			if (!CheckUtils.isEmpty(stu)) {
				RemoteCacheUtils.put(key,stu);
			}
		}
	}
2.数据校验工具类

public class CheckUtils {

	/**
	 * 
	 * TODO 检查checkName对应的值str是否为空,会抛出非法数据异常
	 * @param str
	 * @param checkName
	 * @return void
	 */
	public static void valueIsEmpty(String str, String checkName){
		if(StringUtils.isBlank(str)){
			StringBuffer sb = new StringBuffer();
			sb.append(checkName).append(" must be specified");
			throw new IllegalArgumentException(sb.toString());
		}
	}
	
	/**
	 * TODO 检查key对应的value是否为空
	 * @param value
	 * @param msg
	 * @return void
	 * @author min.zhang
	 * @date: 2017年4月1日 下午5:21:11
	 */
	public static void checkIsNULL(Object value , String msg){
		if(value == null){
			throw new RuntimeException(msg + " is not null");
		}
	}
	
	/**
	 * 判断参数是否非NULL,空字符串,空数组,空的Collection或Map(只有空格的字符串也认为是空串)
	 * @param obj
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isEmpty(Object obj){
		if (obj == null){
			return true;
		}
		if (obj instanceof String && obj.toString().trim().length()==0){
			return true;
		}
		if (obj.getClass().isArray() && Array.getLength(obj)==0){
			return true;
		}
		if (obj instanceof Collection && ((Collection)obj).isEmpty()){
			return true;
		}
		if (obj instanceof Map && ((Map)obj).isEmpty()){
			return true;
		}
		return false;
	}
}
3.远程缓存接口

/**
 * 
 * 描述: 远程集中式缓存接口
 * @author min.zhang
 * @date: 2017年4月1日 下午4:46:10
 */
public interface RemoteCacheService {

	/**
	 * 保存数据
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值 对象
	 */
	public void put(String key, Object value);

	/**
	 * 保存指定有效期的数据
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值对象
	 * @param expireDate
	 *            有效期
	 */
	public void put(String key, Object value, Date expireDate);

	/**
	 * 保存指定有效期的数据
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值对象
	 * @param timeToLive
	 *            有效期为距离当前时间指定的秒数
	 */
	public void put(String key, Object value, int timeToLive);

	/**
	 * 保存指定客户端的数据
	 * 
	 * @param name
	 *            指定客户端
	 * @param key
	 *            键
	 * @param value
	 *            值对象
	 */
	public void putClient(String name, String key, Object value);

	/**
	 * 保存指定客户端的有效期数据
	 * 
	 * @param name
	 *            指定客户端
	 * @param key
	 *            键
	 * @param value
	 *            值对象
	 * @param expireDate
	 *            有效期
	 */
	public void putClient(String name, String key, Object value, Date expireDate);

	/**
	 * 保存指定客户端的有效期数据
	 * 
	 * @param name
	 *            指定客户端
	 * @param key
	 *            键
	 * @param value
	 *            值对象
	 * @param timeToLive
	 *            有效期为距离当前时间指定的秒数
	 */
	public void putClient(String name, String key, Object value, int timeToLive);

	/**
	 * 获取缓存数据
	 * 
	 * @param key
	 *            键
	 * @return 缓存对象
	 */
	public Object get(String key);

	/**
	 * 获取指定类型的缓存数据
	 * 
	 * @param clazz
	 *            指定类型
	 * @param key
	 *            键
	 * @return 指定类型的缓存对象
	 */
	public <T> T get(Class<T> clazz, String key);

	/**
	 * 获取指定客户端的缓存数据
	 * 
	 * @param name
	 *            指定客户端
	 * @param key
	 *            键
	 * @return 指定客户端的缓存对象
	 */
	public Object getClient(String name, String key);

	/**
	 * 获取指定客户端 指定类型的缓存数据
	 * 
	 * @param name
	 *            指定客户端
	 * @param clazz
	 *            指定类型
	 * @param key
	 *            键
	 * @return 指定客户端指定类型的缓存对象
	 */
	public <T> T getClient(String name, Class<T> clazz, String key);

	/**
	 * 移出缓存数据
	 * 
	 * @param key
	 *            键
	 */
	public void remove(String key);

	/**
	 * 移出指定客户端缓存数据
	 * 
	 * @param name
	 *            指定客户端
	 * @param key
	 *            键
	 */
	public void removeClient(String name, String key);

	/**
	 * 清空默认客户端缓存内的数据
	 * 
	 */
	public void clear();

	/**
	 * 清空指定客户端缓存内的数据
	 * 
	 * @param name
	 *            指定客户端
	 */
	public void clearClient(String name);

	/**
	 * 设置默认客户端
	 * 
	 * @param name
	 *            指定客户端
	 */
	public void setDefaultClient(String name);

	public void destory();
	
}
4.实现缓存接口

/**
 * 加上缓存,实现缓存接口的类--提供memcached缓存的实现
 * 描述: MemcachedServiceImpl
 * @author min.zhang
 * @date: 2017年4月1日 下午4:55:22
 */
public class MemcachedServiceImpl implements RemoteCacheService {

	private static ICacheManager<IMemcachedCache> manager;
	private IMemcachedCache cache;
	
	/**
	 * 构造函数
	 * 
	 * @param clientCacheName
	 *            默认客户端名称
	 * @throws RemoteCacheException
	 */
	public MemcachedServiceImpl(String clientCacheName) {
		initCacheManager();
		cache = manager.getCache(clientCacheName);
	}
	
	/**
	 * 
	 * TODO  初始化缓存管理器
	 * @return void
	 * @author min.zhang
	 */
	public synchronized static void initCacheManager(){
		if(manager==null){
			manager = CacheUtil.getCacheManager(IMemcachedCache.class,
					MemcachedCacheManager.class.getName());
			manager.setConfigFile("cache/Memcache.xml");
			// manager.setResponseStatInterval(5*1000);
			manager.start();
		}
	}

	/**
	 * 停止缓存管理器
	 */
	public void destory() {
		if (manager != null) {
			manager.stop();
		}
	}
	
	/**
	 * 检查是否设置默认的客户端
	 * 
	 * @param cache
	 *            默认客户端缓存
	 */
	private IMemcachedCache checkDefaultClient(IMemcachedCache cache) {
		if (cache == null) {
			throw new RuntimeException("默认客户端未定义");
		}
		return cache;
	}

	/**
	 * 设置默认客户端
	 * 
	 * @param name
	 *            默认客户端
	 */
	public void setDefaultClient(String name) {
		cache = this.getClientByName(name);
	}
	
	/**
	 * 获取指定客户端缓存
	 * 
	 * @param name
	 *            客户端名称
	 * @return 缓存对象
	 * @throws RemoteCacheException
	 *             客户端缓存未找到异常
	 */
	private IMemcachedCache getClientByName(String name) {
		IMemcachedCache clientCache = manager.getCache(name);
		if (clientCache == null) {
			throw new RuntimeException("指定的客户端" + name +" 不存在");
		}
		return clientCache;
	}
	
	@Override
	public void put(String key, Object value) {
		this.checkDefaultClient(cache).put(key, value);
	}
	
	@Override
	public void put(String key, Object value, Date expireDate) {
		this.checkDefaultClient(cache).put(key, value, expireDate);
	}
	
	@Override
	public void put(String key, Object value, int timeToLive) {
		this.checkDefaultClient(cache).put(key, value, timeToLive);
	}
	
	@Override
	public void putClient(String name, String key, Object value) {
		this.getClientByName(name).put(key, value);
	}
	
	@Override
	public void putClient(String name, String key, Object value, Date expireDate) {
		this.getClientByName(name).put(key, value, expireDate);
	}
	
	@Override
	public Object getClient(String name, String key) {
		return this.getClientByName(name).get(key);
	}

	@Override
	public void putClient(String name, String key, Object value, int timeToLive) {
		this.getClientByName(name).put(key, value, timeToLive);
	}
	
	@Override
	public Object get(String key) {
		return this.checkDefaultClient(cache).get(key);
	}
	
	@Override
	/**
	 * 得到默认客户端的key对应的类型为clazz的value
	 */
	public <T> T get(Class<T> clazz, String key) {
		T classResult = null;
		Object obj = this.checkDefaultClient(cache).get(key);
		if(obj != null){
		if(obj.getClass().equals(clazz)){
			classResult = (T)obj;
		}else{
			throw new ClassCastException(obj.getClass().getSimpleName()+" 不能强转为: "+clazz.getSimpleName());
		}
		}
		return classResult;
	}
	
	@Override
	/**
	 * 得到指定客户端的key对应的类型为clazz的value
	 */
	public <T> T getClient(String name, Class<T> clazz, String key) {
		T classResult = null;
		Object obj = this.getClientByName(name).get(key);
		if(obj != null){
		if(obj.getClass().equals(clazz)){
			classResult = (T)obj;
		}else{
			throw new ClassCastException(obj.getClass().getSimpleName()+" 不能强转为: "+clazz.getSimpleName());
		}
		}
		return classResult;
	}
	
	@Override
	public void remove(String key) {
		this.checkDefaultClient(cache).remove(key);
	}

	@Override
	public void removeClient(String name, String key) {
		this.getClientByName(name).remove(key);
	}
	
	@Override
	public void clear() {
		this.checkDefaultClient(cache).clear();
	}

	@Override
	public void clearClient(String name) {
		this.getClientByName(name).clear();
	}
}
5.远程缓存工具类

/**
 * 
 * 描述: 远程缓存工具类
 * @author min.zhang
 * @date: 2017年4月1日 下午4:51:01
 */
public class RemoteCacheUtils {

	//key最大长度
	private final static Integer KEY_LENGTH = 3;
	private static Logger logger = LoggerFactory.getLogger(RemoteCacheUtils.class);
	//是否初始化
	private static boolean initialized = false;
	private static RemoteCacheService service = new NoneCacheServiceImpl();
	
	private RemoteCacheUtils(){
		super();
	}
	
	//组件是否完成了初始化
	public static boolean initialized(){
		return initialized && (service!=null);
	}
	
	//组件初始化
	public synchronized static void init(){
		if(initialized()){
			return;
		}
		service = new MemcachedServiceImpl("defaultClient");
		initialized = true;
	}
	
	/**
	 * 保存数据
	 *
	 * @param key
	 *            键
	 * @param value
	 *            值对象
	 */
	public static void put(String key, Object value) {
		try{
		CheckUtils.valueIsEmpty(key, "key");
		CheckUtils.checkIsNULL(value, "value");
		//此处对key的长度做了校验,key做了加密解密操作,略过
		key = checkKeyLength(key);
		//key = key;
		service.put(key, value);
		}catch (Exception e) {
			logger.debug("有错误", e);
		}catch (Throwable e) {
			logger.error(" putting cache find out an error, key:"+key+" value:"+value, e);
		}
	}
	
	/**
	 * 
	 * TODO 长度超过的对key做了封装
	 * @param key
	 * @return
	 * @return String
	 * @author min.zhang
	 * @date: 2017年4月5日 下午1:56:51
	 */
	private static String checkKeyLength(String key){
		//当key的长度超出了指定的长度时,进行MD5压缩
		if(key.getBytes().length> KEY_LENGTH)
			key =md5Digest(key);
		return key ;
	}
	
	/**
     * 使用MD5算法计算摘要,并对结果进行hex转换
     * @param data 源数据
     * @return 摘要信息
     */
    public static String md5Digest(String str){
    	try {
    		byte[] data = str.getBytes("UTF-8");
			MessageDigest md = MessageDigest.getInstance("MD5");
			return Hex.toHex(md.digest(data));
		} catch (Exception e){
			throw new RuntimeException("digest fail!", e);
		}
    }
    
    /**
	 * 获取缓存数据
	 *
	 * @param key
	 *            键
	 * @return Object缓存对象
	 */
	public static Object get(String key) {
		try {
			CheckUtils.valueIsEmpty(key, "key");
			return service.get(key);
		} catch (Throwable e) {
			logger.error(" getting cache find out an error, key:" + key, e);
		}
		return null;
	}
	
}
6.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<memcached>
	<!-- name:Cache的唯一标识;
	socketpool:关联到后面的socketpool配置;
	errorHandler:可选,用来处理出错情况-->
	<client name="defaultClient" compressEnable="true" defaultEncoding="UTF-8" socketpool="defaultPool">
		<errorHandler>com.alisoft.xplatform.asf.cache.memcached.MemcachedErrorHandler</errorHandler>
	</client>
	
	<!-- 
		failover:设置故障转移
		maintSleep:后台线程管理SocketIO池的检查间隔时间,如果设置为0,则表明不需要后台线程维护SocketIO线程池,默认需要管理
		socketTO:Socket操作超时配置,单位ms;
		aliveCheck:表示在使用Socket以前是否先检查Socket状态
	-->
	<socketpool name="defaultPool" failover="true" initConn="1" minConn="1" maxConn="10" maintSleep="0"
		nagle="false" socketTO="3000" aliveCheck="true">
			<servers>cache.bass.3g:12801</servers>
	</socketpool>
</memcached>






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值