cn.kduck.core.cache.CacheWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kduck-core Show documentation
Show all versions of kduck-core Show documentation
The core of the K-Duck development framework encompasses all the featured components of the framework.
package cn.kduck.core.cache;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.Cache;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
/**
* @author LiuHG
*/
public class CacheWrapper implements Cache {
private final Cache cache;
private final ObjectMapper objectMapper;
private final CacheExpiredHandler cacheExpiredHandler;
public CacheWrapper(Cache cache, ObjectMapper objectMapper,CacheExpiredHandler cacheExpiredHandler){
this.cache = cache;
this.objectMapper = objectMapper;
this.cacheExpiredHandler = cacheExpiredHandler;
}
@Override
public String getName() {
return cache.getName();
}
@Override
public Object getNativeCache() {
return cache.getNativeCache();
}
@Override
@Nullable
public ValueWrapper get(Object key) {
return cache.get(key);
}
@Override
@Nullable
public T get(Object key, Class type) {
if(isExpired(key)){
clearByKey(key);
return null;
}
String jsonValue = cache.get(key, String.class);
return json2Bean(jsonValue,type);
}
public List getForList(Object key, Class type) {
if(isExpired(key)){
clearByKey(key);
return null;
}
String jsonValue = cache.get(key, String.class);
return json2ListBean(jsonValue,type);
}
private void clearByKey(Object key) {
cache.evict(key);
}
@Override
@Nullable
public T get(Object key, Callable valueLoader) {
throw new UnsupportedOperationException("不支持此方法");
}
@Override
public void put(Object key, Object value) {
this.put(key, value,null);
}
public void put(Object key, Object value,long expired) {
if(expired > 0){
long expiredTimeMillis = System.currentTimeMillis() + expired * 1000;
this.put(key, value,new Date(expiredTimeMillis));
}else{
this.put(key, value,null);
}
}
public void put(Object key, Object value,Date expired) {
Assert.notNull(key,"缓存key不能为null");
Assert.notNull(key,"缓存value不能为null");
//TODO 处理日期直接过期的情况
String jsonValue = null;
if(value != null){
jsonValue = bean2Json(value);
}
/*
在cacheExpiredHandler中设置value,这样避免分步(先设置永久key,在为该key配置过期时间)设置导致有一定几率无法设置上过期时间。
*/
if(expired != null){
cacheExpiredHandler.doExpired(cache,key,jsonValue,expired);
}else {
cache.put(key, jsonValue);
}
}
public void clearExpired() {
cacheExpiredHandler.clearExpired(cache);
}
private String bean2Json(Object value){
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException("缓存对象转换为Json时错误:" + value.getClass(),e);
}
}
private List json2ListBean(String json,Class type){
if(json == null){
return null;
}
JavaType listType = objectMapper.getTypeFactory().constructParametricType(
List.class, type);
try {
return objectMapper.readValue(json, listType);
} catch (IOException e) {
throw new RuntimeException("缓存对象Json转换为类对象时错误:value->" + json + ",class->" + type,e);
}
}
private T json2Bean(String json,Class type){
if(json == null){
return null;
}
try {
return objectMapper.readValue(json, type);
} catch (IOException e) {
throw new RuntimeException("缓存对象Json转换为类对象时错误:value->" + json + ",class->" + type,e);
}
}
private boolean isExpired(Object key) {
return cacheExpiredHandler.isExpired(cache,key);
}
@Override
@Nullable
public ValueWrapper putIfAbsent(Object key, Object value) {
return cache.putIfAbsent(key, value);
}
@Override
public void evict(Object key) {
cache.evict(key);
// clearExpired();//此行会导致死循环堆栈溢出
}
@Override
public void clear() {
cache.clear();
}
}