Java自动过期本地缓存简单实现

实际项目中常常需要用到本地缓存,特别是一些固定不变的数据,不想频繁调接口,因为http请求本身需要耗时,下面几个类对本地缓存作了简单实现,支持自动过期功能

LocalCache.java

interface LocalCache {

	public void refresh();
}

LocalCacheItem.java

/**
 * 缓存项
 * @author: 
 * @date: 2018年2月6日 下午6:01:33
 */
public class LocalCacheItem {

	// 缓存时间:单位毫秒
	private long cacheTime;
	// 创建时间:单位毫秒
	private long createTime;
	// 缓存值
	private Object value;
	
	public LocalCacheItem() {
		super();
	}

	public LocalCacheItem(long cacheTime, long createTime, Object value) {
		super();
		this.cacheTime = cacheTime;
		this.createTime = createTime;
		this.value = value;
	}

	public long getCacheTime() {
		return cacheTime;
	}
	public void setCacheTime(long cacheTime) {
		this.cacheTime = cacheTime;
	}
	public long getCreateTime() {
		return createTime;
	}
	public void setCreateTime(long createTime) {
		this.createTime = createTime;
	}
	public Object getValue() {
		return value;
	}
	public void setValue(Object value) {
		this.value = value;
	}
	
}

LocalCacheManage.java

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * 本地缓存管理器,CommandLineRunner应用启动执行
 * @author:  
 * @date: 2017年12月20日 上午11:54:53
 */
@Component
public class LocalCacheManage implements CommandLineRunner{

	@Autowired private List localCaches;
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * 应用启动初始化
	 */
	@Override
	public void run(String... args) throws Exception {
		// 1分钟刷新一次,时间可以自定义。这里作为心跳线程,定时刷新缓存
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				if(localCaches!=null && !localCaches.isEmpty()){
					for(LocalCache cache : localCaches){
						try {
							cache.refresh();
						} catch (Exception e) {
							logger.error("本地缓存更新异常", e);
						}
					}
				}
			}
		}, 0, 60000);
	}
	
}

CommomLocalCache.java

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.springframework.stereotype.Component;

/**
 * 公用本地缓存
 * @author:  
 * @date: 2017年12月20日 下午2:18:25
 */
@Component
public class CommomLocalCache implements LocalCache{

	private static ConcurrentHashMap cache = new ConcurrentHashMap<>();
	
	public static boolean containsKey(String key){
		return cache.containsKey(key);
	}
	
	/**
	 * 缓存值
	 * @author:  
	 * @date: 2018年2月6日 下午5:24:20 
	 * @param key
	 * @param value
	 */
	public static void put(String key, Object value){
		LocalCacheItem item = new LocalCacheItem(0, System.currentTimeMillis(), value);
		cache.put(key, item);
	}
	
	/**
	 * 缓存值-指定缓存时间
	 * @author:  
	 * @date: 2018年2月6日 下午5:35:05 
	 * @param key
	 * @param value
	 * @param cacheTime 缓存时间
	 * @param unit 缓存时间单位
	 */
	public static void put(String key, Object value, long cacheTime, TimeUnit unit){
		LocalCacheItem item = new LocalCacheItem(unit.toMillis(cacheTime), System.currentTimeMillis(), value);
		cache.put(key, item);
	}
	
	/**
	 * 获取值
	 * @author:  
	 * @date: 2018年2月6日 下午5:34:28 
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static T get(String key){
		LocalCacheItem item = cache.get(key);
		if(item==null){
			return null;
		}
		return (T)item.getValue();
	}

	@Override
	public void refresh() {
		for(String key : cache.keySet()){
		    LocalCacheItem item = cache.get(key);
		    // 过期了移除缓存
		    long currentTime = System.currentTimeMillis();
	            if(item.getCacheTime()>0 && currentTime - item.getCreateTime() > item.getCacheTime()) {
	        	cache.remove(key);
	            }    
		}
	}

}

拓展:上面的本地缓存控制是通过CommomLocalCache工具类操作key、value,还有一种是嵌入到具体的类中,对类中的map、list进行过期控制,下面是实现方式和示例

AbstractLocalCache.java

import java.util.concurrent.TimeUnit;

/**
 * 本地缓存抽象类
 * LocalCacheManage每隔一分钟执行一次刷新,cacheTime,createTime不设置的,默认就是一分钟更新一次
 * @author:  
 * @date: 2017年12月20日 上午11:53:58
 */
public abstract class AbstractLocalCache implements LocalCache{

	// 缓存时间:单位毫秒
	private long cacheTime;
	// 创建时间:单位毫秒
	private long createTime;
	
	@Override
	public void refresh() {
		// 过期了刷新缓存
		long currentTime = System.currentTimeMillis();
        if(currentTime - createTime > cacheTime) {
            doRefresh();
            this.createTime = System.currentTimeMillis();
        }
	}

	public abstract void doRefresh();

	/**
	 * 指定单位
	 * @author:  
	 * @date: 2017年12月20日 下午12:09:10 
	 * @param cacheTime
	 * @param unit
	 */
	public void setCacheTime(long cacheTime, TimeUnit unit) {
		this.cacheTime = unit.toMillis(cacheTime);
	}

	/**
	 * 毫秒
	 * @author:  
	 * @date: 2017年12月20日 下午12:07:46 
	 * @param cacheTime
	 */
	public void setCacheTime(long cacheTime) {
		this.cacheTime = cacheTime;
	}
	
}

Simple.java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 下面示例表示本地缓存cache 每10分钟清一次
 * @author:  
 * @date: 2018年1月25日 下午2:50:51
 */
public class Simple extends AbstractLocalCache{

	private static Map cacheMap = new HashMap<>();
	private static List cacheList = new ArrayList<>();
	
	@Override
	public void doRefresh() {
		// 清空
		cacheMap.clear();
		cacheList.clear();
		// TODO 重新更新
		// 10分钟
		super.setCacheTime(10, TimeUnit.MINUTES);
	}

} 
  
L
li
L
li
li
L

你可能感兴趣的:(工具使用)