背景:微服務我們要調用字典數據,但是很多都是要重複調用的,沒有緩存,我爲了設置一個應用的緩存,並且可以 定時清理,更新
首先定義兩個靜態數據,。一個軟連接緩存,一個定時清理線程
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); } }