【实用工具类】基于 Guava Cache 实现通用 Token 缓存工具类(附完整源码)

【实用工具类】基于Guava Cache实现通用Token缓存工具类(附完整源码)

在日常开发中,Token缓存是非常常见的场景------比如接口调用的访问令牌、用户登录态Token、第三方服务的临时凭证等。如果每次使用Token都重新生成/请求,会增加系统开销;而手写缓存又容易出现重复造轮子、边界处理不完整的问题。

今天给大家分享一个基于Guava Cache实现的通用Token缓存工具类,支持泛型、自定义配置、自动刷新、失效监听等核心能力,开箱即用,适配绝大多数Token缓存场景。

一、核心特性

这个TokenCache工具类具备以下核心优势:

  • 泛型支持:适配任意类型的Token(String、自定义对象、整数等),无需重复编写缓存逻辑;
  • 灵活配置:支持自定义缓存最大容量、过期时间、并发级别,满足不同场景需求;
  • 自动刷新:获取Token时若不存在/已过期,自动触发刷新逻辑,无需手动判断;
  • 失效监听:缓存失效时可监听并打印原因,便于问题排查;
  • 便捷操作:封装了存、取、失效、清空、统计等常用方法,调用简单。

二、完整源码

先贴出完整的工具类源码,建议直接收藏备用:

java 复制代码
package com.dolphin.util;

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

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

/**
 * 支持泛型的Token缓存类,基于Guava Cache实现
 * 提供Token的存储、获取、自动刷新和失效等功能
 */
public class TokenCache<T> {
    // 基于LRU淘汰策略的核心缓存对象
    private final Cache<String, T> tokenCache;

    // 默认构造函数:最大容量1000,写入后30分钟过期,并发级别16
    public TokenCache() {
        this(1000, 1800, TimeUnit.SECONDS, 16);
    }

    /**
     * 自定义配置的构造函数
     *
     * @param maxSize          最大缓存数量(LRU淘汰阈值)
     * @param expireSeconds    过期时间(写入后多久过期)
     * @param timeUnit         时间单位
     * @param concurrencyLevel 并发级别(同时写缓存的线程数)
     */
    public TokenCache(int maxSize, int expireSeconds, TimeUnit timeUnit, int concurrencyLevel) {
        this.tokenCache = CacheBuilder.newBuilder()
                // LRU核心:缓存达到最大容量时,淘汰最少使用的缓存
                .maximumSize(maxSize)
                // 写入后过期(区别于访问后过期),适合Token这类有固定有效期的场景
                .expireAfterWrite(expireSeconds, timeUnit)
                // 并发级别:控制缓存分段数,提升多线程读写性能
                .concurrencyLevel(concurrencyLevel)
                // 失效监听器:打印失效的Key和原因,便于排查问题
                .removalListener((RemovalListener<String, T>) notification ->
                        System.out.println("Token失效:" + notification.getKey() + ",原因:" + notification.getCause()))
                .build();
    }

    /**
     * 存入/更新Token(覆盖式)
     * @param key   缓存Key(建议按业务规则命名,如user_1_token、api_access_token)
     * @param token 缓存的Token对象
     */
    public void putToken(String key, T token) {
        tokenCache.put(key, token);
    }

    /**
     * 普通获取Token(不存在/已过期返回null)
     * @param key 缓存Key
     * @return 缓存的Token,无则返回null
     */
    public T getToken(String key) {
        return tokenCache.getIfPresent(key);
    }

    /**
     * 带自动刷新的Token获取
     * 若Key不存在/已过期,自动执行refreshLogic生成新Token并缓存
     * @param key          缓存Key
     * @param refreshLogic Token刷新逻辑(Callable接口,支持抛出异常)
     * @return 最新的Token
     */
    public T getTokenWithRefresh(String key, Callable<T> refreshLogic) {
        try {
            return tokenCache.get(key, refreshLogic);
        } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            // 解包RuntimeException,避免外层捕获冗余异常
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            throw new RuntimeException("Token刷新失败", cause);
        }
    }

    /**
     * 强制失效指定Token
     * @param key 缓存Key
     */
    public void invalidateToken(String key) {
        tokenCache.invalidate(key);
    }

    /**
     * 获取当前缓存大小
     * @return 缓存中的有效Key数量
     */
    public long size() {
        return tokenCache.size();
    }

    /**
     * 清空所有缓存
     */
    public void invalidateAll() {
        tokenCache.invalidateAll();
    }
}

三、核心代码解析

1. 依赖说明

该工具类基于Guava Cache实现,需先引入Guava依赖(Maven示例):

xml 复制代码
<!-- Guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version> <!-- 建议使用最新稳定版 -->
</dependency>

2. 关键设计解析

  • LRU淘汰策略 :通过maximumSize设置最大容量,当缓存达到阈值时,自动淘汰最少使用的Token,避免内存溢出;
  • 过期策略 :使用expireAfterWrite(写入后过期),适合Token这类"生成后有固定有效期"的场景(若需"访问后过期",可替换为expireAfterAccess);
  • 泛型设计 :类定义TokenCache<T>,使得缓存可以存储任意类型的Token(字符串、自定义Token对象、整数等);
  • 自动刷新getTokenWithRefresh方法结合Callable,实现"懒加载+自动刷新",无需手动判断Token是否有效;
  • 失效监听removalListener监听缓存失效事件,可扩展为记录日志、发送告警、清理关联数据等。

四、使用示例

下面通过完整示例演示工具类的核心用法:

java 复制代码
public class TokenCacheExample {
    public static void main(String[] args) {
        // 1. 创建默认配置的字符串类型Token缓存
        TokenCache<String> stringCache = new TokenCache<>();

        // 2. 存储Token
        stringCache.putToken("user1_token", "abc123456");

        // 3. 普通获取Token
        String token = stringCache.getToken("user1_token");
        System.out.println("普通获取Token: " + token); // 输出:abc123456

        // 4. 带自动刷新的获取(Token不存在则执行刷新逻辑)
        String newToken = stringCache.getTokenWithRefresh("user2_token", () -> {
            // 此处可替换为实际的Token生成逻辑(如调用接口获取新Token)
            return "new_token_" + System.currentTimeMillis();
        });
        System.out.println("自动刷新后获取Token: " + newToken); // 输出:new_token_17xxxxxxxxx

        // 5. 强制失效Token
        stringCache.invalidateToken("user1_token");
        System.out.println("失效后获取Token: " + stringCache.getToken("user1_token")); // 输出:null

        // 6. 自定义配置的缓存(存储Integer类型,最大容量500,1小时过期,并发级别8)
        TokenCache<Integer> intCache = new TokenCache<>(500, 3600, TimeUnit.SECONDS, 8);
        intCache.putToken("counter", 100);
        System.out.println("整数类型Token: " + intCache.getToken("counter")); // 输出:100

        // 7. 获取缓存大小
        System.out.println("缓存大小: " + intCache.size()); // 输出:1

        // 8. 清空所有缓存
        intCache.invalidateAll();
        System.out.println("清空后缓存大小: " + intCache.size()); // 输出:0
    }
}

五、注意事项与扩展建议

1. 适用场景

该工具类基于本地缓存(Guava Cache),适合单机/低并发场景的Token缓存;若为分布式系统,建议结合Redis实现分布式缓存(可基于该工具类扩展Redis适配层)。

2. 配置优化

  • maximumSize:根据业务场景设置,避免过大导致内存占用过高,过小导致频繁淘汰;
  • expireAfterWrite:建议与Token的实际有效期匹配(如第三方Token有效期1小时,缓存过期时间可设为55分钟,预留刷新时间);
  • concurrencyLevel:默认16,多核CPU场景可适当调大(如32),但不宜过大(会增加分段开销)。

3. 扩展方向

  • 失效监听增强:将System.out.println替换为日志框架(如SLF4J),记录失效详情;
  • 异常处理扩展:针对getTokenWithRefresh的刷新逻辑,增加重试机制;
  • 缓存统计:开启Guava Cache的统计功能(recordStats()),监控缓存命中率、失效次数等;
  • 自定义过期策略:结合业务实现更复杂的过期规则(如不同Key设置不同过期时间)。

六、总结

这个TokenCache工具类封装了Guava Cache的核心能力,通过泛型和便捷的API设计,解决了Token缓存的通用场景需求。代码简洁、易扩展,可直接集成到项目中,减少重复开发成本。

如果你的项目中有Token缓存的需求,不妨试试这个工具类,也欢迎在评论区交流优化建议~


💡 本文源码已亲测可运行,如需更多Guava Cache高级用法,可参考官方文档:Guava Cache官方指南

相关推荐
蜂蜜黄油呀土豆1 天前
Spring 自动装配深度解析:@Autowired、@Resource 与自动注入实战指南
spring boot·spring·autowired·依赖注入·resource
Rover.x1 天前
SpringBoot 项目 JNI 接口无法注入Bean
java·spring boot·spring
古城小栈1 天前
缓存界三座大山:穿透、击穿、雪崩
缓存
前端小白在前进1 天前
★力扣刷题:LRU缓存
spring·leetcode·缓存
ZePingPingZe1 天前
Spring Book什么时候需要整合Spring Cloud?
java·spring·spring cloud
y1y1z1 天前
Spring OAuth 2.0 教程
java·后端·spring
Mr_Xuhhh1 天前
LRU缓存
缓存
honortech1 天前
修改飞书缓存路径
缓存·飞书
小马爱打代码1 天前
Spring AI:搭建自定义 MCP Server:获取 QQ 信息
java·人工智能·spring