实际项目中常常需要用到本地缓存,特别是一些固定不变的数据,不想频繁调接口,因为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<LocalCache> 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<String, LocalCacheItem> 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>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<String, Object> cacheMap = new HashMap<>();
private static List<Object> cacheList = new ArrayList<>();
@Override
public void doRefresh() {
// 清空
cacheMap.clear();
cacheList.clear();
// TODO 重新更新
// 10分钟
super.setCacheTime(10, TimeUnit.MINUTES);
}
}
L
li
L
li
li
L