背景:微服务我们要调用字典数据,但是很多都是要重复调用的,没有缓存,我为了设置一个应用的缓存,并且可以 定时清理,更新
首先定义两个静态数据,。一个软连接缓存,一个定时清理线程
private static SoftReference<Map<String, Map<String, DictionaryVo>>> plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
定时清理逻辑,一分钟清理一次,时间可以自己设置
static {
executorService.scheduleAtFixedRate(() -> {
if (plmDicMapCache.get() != null) {
Map<String, Map<String, DictionaryVo>> stringMapMap = plmDicMapCache.get();
if (stringMapMap != null) {
stringMapMap.clear();
log.info("-----------定时清理字典表缓存 plmDicMapCache-----");
} else {
plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
}
} else {
plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
}
}, 1, 1, TimeUnit.MINUTES);
}
调用方法,以及赋值
public static <T> void convertDicNamePlm(SFunction<T, ?> funcSource, SFunction<T, ?> funcTarget, String groupIdentification, T objects) {
Map<String, Map<String, DictionaryVo>> plmDicList;
Map<String, Map<String, DictionaryVo>> stringMapMap = plmDicMapCache.get();
if (stringMapMap == null) {
plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
stringMapMap = new ConcurrentHashMap<>();
}
if (!stringMapMap.containsKey(groupIdentification)) {
//远程调用的数据方法
plmDicList = getPlmDicList(groupIdentification);
stringMapMap.putAll(plmDicList);
log.info("字典没缓存了======---- {}", groupIdentification);
} else {
Map<String, DictionaryVo> stringDictionaryVoMap = stringMapMap.get(groupIdentification);
plmDicList = new HashMap<>();
plmDicList.put(groupIdentification, stringDictionaryVoMap);
log.info("字典走缓存 {}", groupIdentification);
}
String fieldNameSource = getFieldName(funcSource);
Object fieldValueSource = ReflectUtil.getFieldValue(objects, fieldNameSource);
Map<String, DictionaryVo> stringDictionaryVoMap = plmDicList.get(groupIdentification);
DictionaryVo dictionaryVo = stringDictionaryVoMap.get(fieldValueSource + "");
String fieldNameTarget = getFieldName(funcTarget);
ReflectUtil.setFieldValue(objects, fieldNameTarget, dictionaryVo.getName());
}
这段是根据lamda function 获取数据字段名称,反射赋值
String fieldNameSource = getFieldName(funcSource);
Object fieldValueSource = ReflectUtil.getFieldValue(objects, fieldNameSource);
Map<String, DictionaryVo> stringDictionaryVoMap = plmDicList.get(groupIdentification);
DictionaryVo dictionaryVo = stringDictionaryVoMap.get(fieldValueSource + "");
String fieldNameTarget = getFieldName(funcTarget);
ReflectUtil.setFieldValue(objects, fieldNameTarget, dictionaryVo.getName());
public static <T> void convertDicNamePlm(SFunction<T, ?> funcSource, SFunction<T, ?> funcTarget, String groupIdentification, T objects, Map<String, Map<String, DictionaryVo>> plmDicList) {
String fieldNameSource = getFieldName(funcSource);
Object fieldValueSource = ReflectUtil.getFieldValue(objects, fieldNameSource);
Map<String, DictionaryVo> stringDictionaryVoMap = plmDicList.get(groupIdentification);
DictionaryVo dictionaryVo = stringDictionaryVoMap.get(fieldValueSource + "");
String fieldNameTarget = getFieldName(funcTarget);
ReflectUtil.setFieldValue(objects, fieldNameTarget, dictionaryVo.getName());
}
public static <T> String getFieldName(SFunction<T, ?> func) {
SerializedLambda resolve = LambdaUtils.resolve(func);
String method = resolve.getImplMethodName();
return BeanUtil.getFieldName(method);
}
如何调用呢?拿分页举例:
DictionaryUtil.convertDicNamePlm(DingdingApprovalClassVo::getApproveClass,DingdingApprovalClassVo::getApproveClassName,"dingding_approve_class",record);
public PageResult<DingdingApprovalClassVo> page(PageParameter<DingdingApprovalClassVo> parameter) {
Page<DingdingApprovalClassVo> queryPage = PageUtil.getPage(parameter, true);
Page<DingdingApprovalClassVo> resultPageList = dingdingApprovalClassMapper.queryListPage(queryPage, parameter.getSelectParameter());
for (DingdingApprovalClassVo record : resultPageList.getRecords()) {
//这里是赋值
DictionaryUtil.convertDicNamePlm(DingdingApprovalClassVo::getApproveClass,DingdingApprovalClassVo::getApproveClassName,
"dingding_approve_class",record);
}
return new PageResult<>(resultPageList);
}
完整代码
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
import com.orderplus.core.enumeration.ReturnCode;
import com.orderplus.core.feign.BambooService;
import com.orderplus.core.feign.PublicService;
import com.orderplus.core.handle.BusinessException;
import com.orderplus.core.vo.pdm.DictionaryVo;
import com.orderplus.core.vo.publicService.CommonVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.lang.ref.SoftReference;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
public class DictionaryUtil {
private static SoftReference<Map<String, Map<String, DictionaryVo>>> plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
static {
executorService.scheduleAtFixedRate(() -> {
if (plmDicMapCache.get() != null) {
Map<String, Map<String, DictionaryVo>> stringMapMap = plmDicMapCache.get();
if (stringMapMap != null) {
stringMapMap.clear();
log.info("-----------定时清理字典表缓存 plmDicMapCache-----");
} else {
plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
}
} else {
plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
}
}, 1, 1, TimeUnit.MINUTES);
}public static Map<String, Map<String, DictionaryVo>> getPlmDicList(String... groupIdentification) {
BambooService bean = ApplicationContextProvider.getBean(BambooService.class);
Result<List<DictionaryVo>> resp = bean.queryCommonDictionaryByGroups(Arrays.asList(groupIdentification));
log.info("BambooService.queryBaseDictionary resp:{}", JSON.toJSONString(resp));
if (resp == null) {
throw new BusinessException(ReturnCode.PUBLIC_CALL_ERR);
}
if (!ReturnCode.success.getCode().equals(resp.getCode())) {
throw new BusinessException(resp.getCode(), resp.getMsg(), null);
}
List<DictionaryVo> data = resp.getData();
if (CollectionUtil.isEmpty(data)) {
return new HashMap<>();
}
Map<String, List<DictionaryVo>> dicMap = data.stream().collect(Collectors.groupingBy(DictionaryVo::getGroupIdentification));
Map<String, Map<String, DictionaryVo>> dicMapGroup = new LinkedHashMap<>();
dicMap.forEach((k, v) -> {
Map<String, DictionaryVo> map = v.stream().collect(Collectors.toMap(DictionaryVo::getValue, Function.identity(), (v1, v2) -> v1));
dicMapGroup.put(k, map);
});
return dicMapGroup;
}
public static <T> void convertDicNamePlm(SFunction<T, ?> funcSource, SFunction<T, ?> funcTarget, String groupIdentification, T objects) {
Map<String, Map<String, DictionaryVo>> plmDicList;
Map<String, Map<String, DictionaryVo>> stringMapMap = plmDicMapCache.get();
if (stringMapMap == null) {
plmDicMapCache = new SoftReference<>(new ConcurrentHashMap<>());
stringMapMap = new ConcurrentHashMap<>();
}
if (!stringMapMap.containsKey(groupIdentification)) {
plmDicList = getPlmDicList(groupIdentification);
stringMapMap.putAll(plmDicList);
log.info("字典没缓存了======---- {}", groupIdentification);
} else {
Map<String, DictionaryVo> stringDictionaryVoMap = stringMapMap.get(groupIdentification);
plmDicList = new HashMap<>();
plmDicList.put(groupIdentification, stringDictionaryVoMap);
log.info("字典走缓存 {}", groupIdentification);
}
String fieldNameSource = getFieldName(funcSource);
Object fieldValueSource = ReflectUtil.getFieldValue(objects, fieldNameSource);
Map<String, DictionaryVo> stringDictionaryVoMap = plmDicList.get(groupIdentification);
DictionaryVo dictionaryVo = stringDictionaryVoMap.get(fieldValueSource + "");
String fieldNameTarget = getFieldName(funcTarget);
ReflectUtil.setFieldValue(objects, fieldNameTarget, dictionaryVo.getName());
}
public static <T> void convertDicNamePlm(SFunction<T, ?> funcSource, SFunction<T, ?> funcTarget, String groupIdentification, T objects, Map<String, Map<String, DictionaryVo>> plmDicList) {
String fieldNameSource = getFieldName(funcSource);
Object fieldValueSource = ReflectUtil.getFieldValue(objects, fieldNameSource);
Map<String, DictionaryVo> stringDictionaryVoMap = plmDicList.get(groupIdentification);
DictionaryVo dictionaryVo = stringDictionaryVoMap.get(fieldValueSource + "");
String fieldNameTarget = getFieldName(funcTarget);
ReflectUtil.setFieldValue(objects, fieldNameTarget, dictionaryVo.getName());
}
public static <T> String getFieldName(SFunction<T, ?> func) {
SerializedLambda resolve = LambdaUtils.resolve(func);
String method = resolve.getImplMethodName();
return BeanUtil.getFieldName(method);
}
}