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

如何为Caffeine Cache单条目设动态TTL?Policy为空问题求解

问题根源

你现在的Caffeine缓存用了expireAfterWrite固定过期策略,这种配置下缓存不支持可变过期(Variable Expiration),所以调用nativeCache.policy().expireVariably()会返回空的Optional,直接get()就会触发空指针异常。

解决办法

1. 调整Caffeine配置,开启可变过期支持

必须修改你的Caffeine Bean配置,把固定过期换成支持可变过期的配置,两种可选方式:

方式一:直接开启可变过期

如果不需要默认过期时长,直接用这个配置:

@Bean
public Caffeine CaffeineCacheConfig() {
    return Caffeine.newBuilder()
            .expireVariably() // 核心:开启可变过期支持
            .initialCapacity(1000)
            .maximumSize(1200);
}

方式二:保留默认过期+支持自定义

要是想给大部分缓存条目留个默认过期时间,同时允许个别条目自定义过期时长,就用自定义Expiry的方式:

@Bean
public Caffeine CaffeineCacheConfig() {
    return Caffeine.newBuilder()
            .expireAfter(new Expiry<Object, Object>() {
                @Override
                public long expireAfterCreate(Object key, Object value, long currentTime) {
                    // 默认创建后5分钟过期,和你原配置一致
                    return TimeUnit.MINUTES.toNanos(5);
                }

                @Override
                public long expireAfterUpdate(Object key, Object value, long currentTime, long currentDuration) {
                    // 更新后沿用剩余过期时长,可按需修改
                    return currentDuration;
                }

                @Override
                public long expireAfterRead(Object key, Object value, long currentTime, long currentDuration) {
                    // 读取后沿用剩余过期时长,可按需修改
                    return currentDuration;
                }
            })
            .initialCapacity(1000)
            .maximumSize(1200);
}

这种方式下,缓存既有默认过期规则,也能通过VarExpiration接口单独修改某条缓存的过期时间。

2. 给业务方法加空指针防护

就算配置正确,也建议给Optional做非空判断,避免意外报错:

@Override
public void addObjectToCacheWithExpiry(CaffeineCacheManager caffeineCacheManager, String cacheName, String key, Object value, long duration, TimeUnit timeUnit) {
    CaffeineCache caffeineCache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
    if (caffeineCache == null) {
        throw new IllegalArgumentException("缓存[" + cacheName + "]不存在");
    }
    Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
    // 用ifPresent避免空指针
    nativeCache.policy().expireVariably().ifPresent(varExpiration -> {
        varExpiration.put(key, value, duration, timeUnit);
    });
}
重要提示
  • 只有当缓存构建时配置了expireVariably()或者自定义Expiry实现,policy().expireVariably()才会返回非空的结果。
  • 若同时配置了固定过期(如expireAfterWrite)和可变过期,固定策略会被覆盖,缓存将完全遵循可变过期规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:40:38