微服务想缓存一些数据,不希望重复调用。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);
    }
}

 

posted @ 2024-04-27 11:39  _Phoenix  阅读(22)  评论(0编辑  收藏  举报