You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定时刷新安全Token并复用?Spring环境实现方案问询

可行解决方案:Token复用与自动刷新实现

核心思路

创建一个专门的Token管理组件,维护当前有效Token,通过定时任务主动刷新,同时给需要Token的组件提供获取最新Token的入口,替代直接注入固定Token的方式。


方案1:基础定时刷新实现

1. 编写Token管理组件

@Component
@EnableScheduling
public class TokenManager {
    private final Authorization authorization;
    // volatile保证多线程下的可见性,避免线程读取过期的旧Token
    private volatile String currentToken;

    // 容器初始化时立即获取第一个Token
    public TokenManager(Authorization authorization) {
        this.authorization = authorization;
        this.currentToken = authorization.getToken();
    }

    // 每4分钟自动刷新Token(配置可通过外部参数覆盖)
    @Scheduled(fixedDelayString = "${fixed.delay:PT4M}")
    public void refreshToken() {
        this.currentToken = authorization.getToken();
    }

    // 对外提供获取最新Token的方法
    public String getCurrentToken() {
        return currentToken;
    }
}

2. 修改业务组件依赖

将原来直接注入String token改为注入TokenManager,每次请求时获取最新Token:

@Component
public class Manager {
    private final String path;
    private final TokenManager tokenManager;
    private final RestOperations restOperations;

    public Manager(
            @Value("${my.path}") String path,
            TokenManager tokenManager,
            RestOperations restOperations) {
        this.path = path;
        this.tokenManager = tokenManager;
        this.restOperations = restOperations;
    }

    public Object restCall() {
        // 获取最新的有效Token
        String validToken = tokenManager.getCurrentToken();
        // 携带Token发起请求
        // 示例:restOperations.exchange(path, HttpMethod.GET, new HttpHeaders(){{setBearerAuth(validToken)}}, Object.class);
        return null;
    }
}

方案2:增加兜底刷新逻辑(更健壮)

如果担心定时任务因异常失效,可在获取Token时增加双重检查,主动触发刷新:

@Component
@EnableScheduling
public class TokenManager {
    private final Authorization authorization;
    private volatile String currentToken;
    private volatile long lastRefreshTime;
    // 4分钟刷新间隔(毫秒)
    private static final long REFRESH_INTERVAL = 4 * 60 * 1000;

    public TokenManager(Authorization authorization) {
        this.authorization = authorization;
        refreshToken();
    }

    @Scheduled(fixedDelayString = "${fixed.delay:PT4M}")
    public void refreshToken() {
        this.currentToken = authorization.getToken();
        this.lastRefreshTime = System.currentTimeMillis();
    }

    public String getCurrentToken() {
        // 双重检查:如果距离上次刷新超过4分钟,主动触发刷新
        if (System.currentTimeMillis() - lastRefreshTime > REFRESH_INTERVAL) {
            synchronized (this) {
                if (System.currentTimeMillis() - lastRefreshTime > REFRESH_INTERVAL) {
                    refreshToken();
                }
            }
        }
        return currentToken;
    }
}

原方案问题说明

  • @Scheduled修饰的方法必须为void,无法通过返回值更新Bean;
  • @Bean注解的方法仅在Spring容器初始化时执行一次,后续不会因@Scheduled重复执行,无法动态更新Token实例。

内容的提问来源于stack exchange,提问作者karvai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:50:24