java 非常好用的一个缓存(Google Guava的Cache)

基本每个web项目都少不了缓存,通常很时候都会选择redis作缓存,或者自己用map轻松实现,但上面这两种缓存有时满足不了需求,有时觉得redis作缓存有点重,而map手功实现又太轻或功能不足时(缓存时过期实现),此时选googleCache是一个不错的选择,它不仅使用简单而且功能也丰富。

1 引入googleCache包:

XML 复制代码
  <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>

2 googleChache代码:

代码实现很简单,参数根据自己的项目情况调整 如下:

XML 复制代码
/**
 * MemCacheServiceImpl用于提供内存缓存服务的实现类
 * 使用Google Guava库中的CacheBuilder创建缓存对象
 */
@Service
public class MemCacheServiceImpl {

    // 内存缓存对象,使用Google Guava的CacheBuilder进行配置和构建
    private static Cache<String, Object> cache = CacheBuilder.newBuilder()
            .initialCapacity(500)              // 初始容量
            .maximumSize(2000)                 // 最大容量,超过时按LRU(最近最少使用)算法清除缓存项
            .concurrencyLevel(8)               // 并发级别,用于并发访问控制
            .expireAfterWrite(2, TimeUnit.MINUTES) // 写入后过期时间,单位为分钟
            .build();

    /**
     * 将键值对存入缓存
     *
     * @param key   缓存键
     * @param value 缓存值
     */
    public void put(String key, Object value) {
        cache.put(key, value);
    }

    /**
     * 根据键获取缓存值
     *
     * @param key 缓存键
     * @return 对应的缓存值,如果不存在则返回null
     */
    public Object get(String key) {
        return cache.getIfPresent(key);
    }
}

3 应用场景

在项目本身项目已使用redis做了全局缓存了,但redis做缓存对于小的数据量反应很快,大一点的数据会相对慢一些,如果拿来来的数据还要做处理,如还原对象,这本般也浪费时间,在这过程再加多一个内存缓存就更完美了,如以下代码:

java 复制代码
/**
 * 获取所有充电桩枪关系列表
 *
 * @return ChargePoleRelationGun对象列表
 */
public List<ChargePoleRelationGun> getGunList() {
    // 定义缓存键
    String cacheKey = "All_GNG";

    List<ChargePoleRelationGun> list;
    
    // 从缓存中获取对象
    Object obj = MemCacheServiceImpl.getObj(cacheKey);
    
    // 如果缓存中有对象并且不为空,则直接返回
    if (obj != null && !(list = (List<ChargePoleRelationGun>) obj).isEmpty()) {
        return list;
    }

    // 从Redis中获取所有符合模式的key
    Set<String> keys = stringRedisTemplate.keys("t_chargePoleRelationGun:*");
    
    // 如果Redis中没有符合模式的key,则返回空列表
    if (keys.isEmpty()) {
        return Collections.emptyList();
    }

    // 将获取的key集合转为列表,然后通过Redis模板批量获取对应的值列表
    List<String> keyList = new ArrayList<>(keys);
    List<String> values = stringRedisTemplate.opsForValue().multiGet(keyList);

    // 初始化结果列表
    list = new ArrayList<>();

    // 记录开始时间,用于性能统计
    long xStart = System.currentTimeMillis();
    
    // 遍历获取的值列表,解析为ChargePoleRelationGun对象并加入结果列表
    for (int i = 0; i < keyList.size(); i++) {
        //String key = keyList.get(i);
        String storedValue = values.get(i);

        // 解析JSON字符串为ChargePoleRelationGun对象
        ChargePoleRelationGun value = JSONObject.parseObject(storedValue, ChargePoleRelationGun.class);

        // 如果解析成功且枪号不为空,则将对象加入结果列表
        if (value != null) {
            if (StringUtil.isNotNull(value.getGunNo())) {
                list.add(value);
            }
        }
    }

    // 打印性能统计信息
    System.out.println("time -> " + (System.currentTimeMillis() - xStart));

    // 根据充电桩ID排序结果列表
    list.sort(Comparator.comparing(ChargePoleRelationGun::getPoleId));

    // 将结果列表放入缓存
    MemCacheServiceImpl.putObj(cacheKey, list);

    // 返回结果列表
    return list;
}

4 扩展资料

Guava 是一个 Google 开发的开源 Java 库,包含了大量工具类和常用功能,可以帮助开发人员提高开发效率和代码质量。Guava 的工具类可以分为以下几类:

  • 集合工具类:包含了 Lists、Sets、Maps 等集合工具类,提供了丰富的集合操作方法,可以简化集合操作的代码。
  • 缓存工具类:包含了 CacheBuilder、CacheLoader 等缓存工具类,可以帮助开发人员实现高效的缓存。
  • 原生类型支持:包含了 Primitives、Longs、Ints 等原生类型支持类,提供了原生类型的常用操作方法。
  • 并发性工具类:包含了 ConcurrentMap、Semaphore、CountDownLatch 等并发性工具类,可以帮助开发人员实现安全、高效的并发编程。
  • 常见注解:包含了 NotNull、Nullable 等常见注解,可以帮助开发人员进行代码规范检查。
  • 字符串处理:包含了 Joiner、Splitter 等字符串处理工具类,可以帮助开发人员简化字符串处理的代码。
  • IO 流工具类:包含了 Files、Resources、ByteStreams 等 IO 流工具类,可以帮助开发人员简化 IO 流操作的代码。

Guava 工具类的一些常用用例:

  • 使用集合工具类简化集合操作的代码。例如,使用 Lists.newArrayList() 方法可以创建一个空的 List,使用 Lists.asList() 方法可以将一个数组转换为一个 List。
  • 使用缓存工具类实现高效的缓存。例如,使用 CacheBuilder 可以创建一个缓存,使用 CacheLoader 可以实现缓存数据的自动加载。
  • 使用原生类型支持简化原生类型的操作。例如,使用 Longs.compare() 方法可以比较两个 long 值。
  • 使用并发性工具类实现安全、高效的并发编程。例如,使用 ConcurrentMap 可以实现线程安全的 Map。
  • 使用常见注解进行代码规范检查。例如,使用 NotNull 注解可以检查方法参数是否为非空。
  • 使用字符串处理工具类简化字符串处理的代码。例如,使用 Joiner.on(", ") 方法可以将多个字符串用逗号连接起来。
  • 使用 IO 流工具类简化 IO 流操作的代码。例如,使用 Files.readAllBytes() 方法可以读取一个文件的所有字节。

Guava 工具类可以帮助开发人员提高开发效率和代码质量,是 Java 开发人员必备的工具。

相关推荐
Coder_Boy_20 分钟前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
失忆爆表症37 分钟前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
invicinble38 分钟前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
小迷糊的学习记录38 分钟前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜1 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试
较真的菜鸟1 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖1 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
不爱吃糖的程序媛1 小时前
Flutter 与 OpenHarmony 通信:Flutter Channel 使用指南
前端·javascript·flutter
利刃大大1 小时前
【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu
前端·javascript·vue.js·element-plus
NEXT061 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain