Token 管理工具

下面是一套 真正通用、可复用、与具体平台完全解耦的 Token 管理工具设计,满足:

  • 不绑定企业微信
  • ✅ 支持 任意第三方(OAuth / 内部系统 / API Token)
  • ✅ 自动缓存
  • ✅ 自动过期刷新
  • ✅ 并发安全
  • ✅ 可 Spring 注入
  • ✅ 你现在的企业微信 / 以后阿里云 / 钉钉 / 自研系统都能用

一、设计目标(一句话)

TokenManager 只负责:缓存 + 过期判断 + 刷新调度至于"怎么获取 Token",交给调用方提供

👉 这就是策略模式 + 缓存池

二、核心抽象(这是关键)

1️⃣ 通用 Token 接口(不是企业微信)

plain 复制代码
public interface AccessToken {

    /** 获取 token 字符串 */
    String getToken();

    /** 是否已过期 */
    boolean isExpired();
}

2️⃣ 通用 Token 刷新器(最重要)

plain 复制代码
@FunctionalInterface
public interface TokenProvider {

    /**
     * 获取新的 token
     * 由调用方实现(HTTP / SDK / DB / 本地算法 都行)
     */
    AccessToken refresh();
}

⚠️ 注意:TokenManager 完全不知道 token 从哪来

三、通用 TokenManager(核心实现)✅

plain 复制代码
@Component
public class TokenManager {

    /** Token 缓存池 */
    private final Map<String, AccessToken> tokenCache = new ConcurrentHashMap<>();

    /** 锁池(避免全局锁) */
    private final Map<String, Object> lockMap = new ConcurrentHashMap<>();

    /**
     * 获取 token(通用)
     *
     * @param key           token 唯一标识(非常重要)
     * @param tokenProvider token 刷新逻辑
     */
    public String getToken(String key, TokenProvider tokenProvider) {
        AccessToken token = tokenCache.get(key);

        if (token == null || token.isExpired()) {
            // 每个 key 一把锁
            Object lock = lockMap.computeIfAbsent(key, k -> new Object());

            synchronized (lock) {
                token = tokenCache.get(key);
                if (token == null || token.isExpired()) {
                    token = tokenProvider.refresh();
                    tokenCache.put(key, token);
                }
            }
        }
        return token.getToken();
    }

    /** 主动清除(可选) */
    public void invalidate(String key) {
        tokenCache.remove(key);
        lockMap.remove(key);
    }
}

📌 这是一个"平台无关"的基础设施类

四、一个通用 Token 实现(可直接用)

plain 复制代码
public class DefaultAccessToken implements AccessToken {

    private final String token;
    private final long expireAt;

    public DefaultAccessToken(String token, long expiresInSeconds) {
        this.token = token;
        // 提前 5 分钟过期
        this.expireAt = System.currentTimeMillis() + (expiresInSeconds - 300) * 1000;
    }

    @Override
    public String getToken() {
        return token;
    }

    @Override
    public boolean isExpired() {
        return System.currentTimeMillis() >= expireAt;
    }
}

五、使用示例(重点:看有多通用)

✅ 1️⃣ 企业微信(你现在的需求)

plain 复制代码
String token = tokenManager.getToken(
    "wx:login",
    () -> {
        WxTokenDTO dto = callWxApi();
        return new DefaultAccessToken(dto.getAccess_token(), dto.getExpires_in());
    }
);

✅ 2️⃣ 钉钉 Token

plain 复制代码
String token = tokenManager.getToken(
    "dingding:token",
    () -> {
        DingTokenDTO dto = dingApi.getToken();
        return new DefaultAccessToken(dto.getAccessToken(), dto.getExpireIn());
    }
);

✅ 3️⃣ 阿里云 RAM Token

plain 复制代码
String token = tokenManager.getToken(
    "aliyun:ram",
    () -> new DefaultAccessToken(fetchAliyunToken(), 3600)
);

✅ 4️⃣ 自研系统 API Token

plain 复制代码
String token = tokenManager.getToken(
    "internal:api",
    () -> new DefaultAccessToken(loginAndGetToken(), 7200)
);

✅ 5️⃣ 本地算法生成 Token(JWT)

plain 复制代码
String token = tokenManager.getToken(
    "jwt:system",
    () -> new DefaultAccessToken(jwtService.generate(), 1800)
);

六、为什么这个方案是"工程级"的?

说明
✅ 完全解耦 TokenManager 不依赖任何平台
✅ 策略模式 TokenProvider 决定"怎么拿 token"
✅ 高并发安全 每个 key 独立锁
✅ 可扩展 新平台不改一行管理代码
✅ 可测试 TokenProvider 可 mock
✅ 可缓存 Map / Redis 都能替换

七、进阶(如果你后面会分布式)

如果你以后是 多节点部署,只需要把:

plain 复制代码
Map<String, AccessToken> tokenCache

换成:

  • Redis
  • Caffeine
  • Guava Cache

👉 TokenManager 设计完全不用变

八、你现在项目中可以这样分层(建议)

plain 复制代码
infrastructure/
 └── token/
     ├── TokenManager.java
     ├── AccessToken.java
     ├── TokenProvider.java
     └── DefaultAccessToken.java

企业微信、钉钉、阿里云都只是 TokenProvider 的实现

相关推荐
于先生吖39 分钟前
Java框架开发短剧漫剧系统:后台管理与接口开发
java·开发语言
daidaidaiyu1 小时前
Spring IOC 源码学习 声明式事务的入口点
java·spring
myloveasuka1 小时前
[Java]查找算法&排序算法
java·算法·排序算法
清水白石0082 小时前
Free-Threaded Python 实战指南:机遇、风险与 PoC 验证方案
java·python·算法
发际线还在2 小时前
互联网大厂Java三轮面试全流程实战问答与解析
java·数据库·分布式·面试·并发·系统设计·大厂
_周游2 小时前
Kaptcha—Google验证码工具
java·intellij-idea·jquery
我真会写代码2 小时前
深入理解JVM GC:触发机制、OOM关联及核心垃圾回收算法
java·jvm·架构
本喵是FW3 小时前
C语言手记1
java·c语言·算法
洛阳泰山3 小时前
MaxKB4j Docker Compose 部署指南
java·docker·llm·springboot·rag·maxkb4j
森林里的程序猿猿3 小时前
垃圾收集器G1和ZGC
java·jvm·算法