微服務想緩存一些數據,不希望重複調用。java SoftReference軟引用存儲緩存

背景:微服務我們要調用字典數據,但是很多都是要重複調用的,沒有緩存,我爲了設置一個應用的緩存,並且可以 定時清理,更新

 

首先定義兩個靜態數據,。一個軟連接緩存,一個定時清理線程

 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);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章