Guava Cache用法介绍

一、Guava是什么

Guava是一种基于开源的Java库,Google Guava源于2007年的"Google Collections Library"。这个库是为了方便编码,并减少编码错误。这个库用于提供集合,缓存,支持原语句,并发性,常见注解,字符串处理,I/O和验证的实用方法。

二、Guava Cache是什么

Guava cache是谷歌的Guva提供的cache模块,目前被常用在单机上的本地缓存,如果是分布式,它就无能为力。(本地缓存详见:https://my.oschina.net/u/2270476/blog/1805749)

Guava Cache与ConcurrentMap很相似,但也不完全一样。最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除。相对地,Guava Cache为了限制内存占用,通常都设定为自动回收元素。在某些场景下,尽管LoadingCache 不回收元素,它也是很有用的,因为它会自动加载缓存。

Guava Cache是在内存中缓存数据,相比较于数据库或redis存储,访问内存中的数据会更加高效。Guava官网介绍,下面的这几种情况可以考虑使用Guava Cache:

  1. 愿意消耗一些内存空间来提升速度。

  2. 预料到某些键会被多次查询。

  3. 缓存中存放的数据总量不会超出内存容量。

所以,可以将程序频繁用到的少量数据存储到Guava Cache中,以改善程序性能。具体的详细用法详见:https://www.cnblogs.com/fnlingnzb-learner/p/11022152.html

三、本次项目使用Guava Cache方法代码片段:

1、服务启动时加载缓存

package cn.uce.rms.common.cache;

import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import cn.uce.rms.comm.entity.RmsGroupTransportEntity;
import cn.uce.rms.monitor.biz.IRmsGroupBiz;

/**
 * 本地缓存
 * @Description guava
 * @date 2018年12月06日 16:49:00
 */
@Component("monitorLocalCache")
public class MonitorLocalCache implements InitializingBean {

    /**
     * 日志
     */
    private static final Logger log = LoggerFactory.getLogger(MonitorLocalCache.class);

    /**
     * 缓存 2小时未被读/写访问则回收
     */
    private Cache> transportCache;
    /**
     * 缓存有效时间
     */
    private static final int CACHE_ACCESS_DURATION = 2;
    
    /**
     * 运输班次缓存Key
     */
    private static final String TRANSPORT_GROUP_CACHE = "TRANSPORT_GROUP_CACHE";

    @Resource
    private IRmsGroupBiz rmsGroupBiz;

    @Override
    public void afterPropertiesSet() {
        // 缓存有效时长2小时
        transportCache = CacheBuilder.newBuilder().expireAfterWrite(CACHE_ACCESS_DURATION, TimeUnit.HOURS)
                .removalListener(notification -> log.info("[transport Cache Data] == {} was removed, cause is {}",
                        notification.getKey(), notification.getCause())).recordStats().build();
    }

    /**
     * 将所有缓存的值置失效
     * @Description
     * @date 2018年12月23日 12:14:22
     */
    public void invalidateAllLocalCache() {
        // 运输班次
        transportCache.invalidateAll();
    }
    
    /**
     * 获取运输班次缓存数据
     * @Description
     * @return 运输班次结果集
     * @throws ExecutionException 执行缓存异常
     * @date 2018年12月06日 16:59:14
     */
    public List transportGroupCache() throws ExecutionException {
        // 获取RMS运输班次数据
        return transportCache.get(TRANSPORT_GROUP_CACHE, () -> rmsGroupBiz.findTransportGroupFromProduct());
    }
}

2、需要用到缓存时调用 

/**
 *
 * @Description
 * @date 2019年01月22日 11:57:00
 */
@Component("groupCacheSupport")
public class GroupCacheSupport {

    /**
     * 日志收集
     */
    private static final Logger log = LoggerFactory.getLogger(GroupCacheSupport.class);


    /**
     * 本地缓存
     */
    @Resource
    private MonitorLocalCache monitorLocalCache;

    public Map> findTransportMapGroupByGroupName() {
         List resultList;
         resultList = monitorLocalCache.transportGroupCache();
try {
            resultList = monitorLocalCache.transportGroupCache();
            // 过滤主班次
            List newList = resultList.stream().filter(item -> item.getGroupType().equals(SUB.value())).collect(Collectors.toList());
            // 按班次名称分组
            Map> collect = newList.stream().collect(groupingBy(RmsGroupTransportEntity::getTransportGroupName));
            for (String transportGroupName : collect.keySet()) {
                // 以组列号作为Key生成Map,用于去重
                Map> groupMap =
                        collect.get(transportGroupName).stream().collect(groupingBy(RmsGroupTransportEntity::getGroupOnlyoneCode));
                // 获取当中的一个元素即可
                List tmpList = new ArrayList<>(groupMap.get(groupMap.keySet().iterator().next()));
                // 排序
                tmpList.sort(comparing(RmsGroupTransportEntity::getSubSortNum));
                // 覆盖原有的元素
                resultMap.put(transportGroupName, tmpList);
            }
        } catch (ExecutionException e) {
            log.error("获取运输班次时执行缓存失败", e);
        }
        return resultMap;
    }
}

 

你可能感兴趣的:(数据库)