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

如何为RedisCacheManager设置特定时间(如午夜)过期缓存?

如何让RedisCacheManager的缓存在特定时间(如午夜)过期?

刚上手RedisCacheManager,已经搞定了一天有效期的缓存,现在想改成特定时间(比如午夜)过期?这需求太常见了,我给你分享几个靠谱的实现方式:

方法一:动态计算到目标时间的间隔(单个Key生效)

这是最直接的思路,不用改动太多现有代码。核心就是不使用固定的过期时长,而是计算当前时间到你目标过期时间(比如次日午夜)的毫秒差,把这个差值作为缓存的过期时间。

举个Spring项目里的Java代码示例:

// 计算当前时间到次日午夜的毫秒数
LocalDateTime now = LocalDateTime.now();
// 构造次日0点0分0秒的时间
LocalDateTime midnight = now.plusDays(1)
                           .withHour(0)
                           .withMinute(0)
                           .withSecond(0)
                           .withNano(0);
// 计算时间差
long expireMillis = Duration.between(now, midnight).toMillis();

// 存入缓存时使用这个动态计算的过期时间
redisCacheManager.getCache("myCache").put("targetKey", "cacheValue", expireMillis);

注意:每次存入缓存时都要重新计算这个间隔,因为不同时间存入的Key,到午夜的剩余时间是不一样的。

方法二:自定义CacheManager全局配置(批量生效)

如果想让某一类甚至所有缓存都默认在午夜过期,可以自定义RedisCacheConfiguration,动态生成过期时间。

不过要注意:直接在Bean初始化时计算一次过期时间是不行的(因为CacheManager是单例,只会用启动时的计算值),所以要确保每次创建缓存时都能动态获取最新的过期间隔。

示例代码如下:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
    
    // 基础缓存配置(序列化、默认规则等)
    RedisCacheConfiguration baseConfig = RedisCacheConfiguration.defaultCacheConfig()
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

    return RedisCacheManager.builder(cacheWriter)
            // 全局默认配置(如果需要所有缓存都用午夜过期,就把这里的entryTtl改成动态计算的)
            .cacheDefaults(baseConfig.entryTtl(Duration.ofMillis(calculateMidnightExpireMillis())))
            // 也可以给特定缓存单独配置
            .withCacheConfiguration("userCache", baseConfig.entryTtl(Duration.ofMillis(calculateMidnightExpireMillis())))
            .build();
}

// 封装计算过期时间的工具方法
private long calculateMidnightExpireMillis() {
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime midnight = now.plusDays(1).truncatedTo(ChronoUnit.DAYS);
    return Duration.between(now, midnight).toMillis();
}

小提示:如果你的项目里有多个缓存需要不同的过期规则,用withCacheConfiguration逐个配置就好,灵活性很高。

方法三:定时任务主动清理缓存(简单粗暴)

如果你的业务场景不需要精确到每个Key的过期时间,只要每天午夜清空指定缓存就行,那用定时任务是最简单的方案。

比如用Spring的@Scheduled注解实现:

// 每天0点0分0秒执行
@Scheduled(cron = "0 0 0 * * ?")
public void clearCacheAtMidnight() {
    // 清空指定缓存
    redisCacheManager.getCache("myCache").clear();
    // 如果要清空所有缓存,可以遍历cacheManager.getCacheNames()逐个清理
}

注意:这种方式会直接清空整个缓存,不管里面的Key是什么时候存入的,适合那些每天必须刷新的缓存场景(比如每日统计数据)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:50:09