Spring Boot 如何在每个条目的基础上向Caffeine缓存添加动态TTL

kkih6yb8  于 2023-06-22  发布在  Spring
关注(0)|答案(1)|浏览(163)

我想提供一个签名为-

`public void addObjectToCacheWithExpiry(CaffeineCacheManager caffeineCacheManager, String cacheName, String key, Object value, long duration, TimeUnit timeUnit)`

这样我就可以在特定缓存中放入一个值,并将持续时间作为参数传递。
Ben Caffeine Cache - Specify expiry for an entry提供了一些解释

`.  @Override
    public void addObjectToCacheWithExpiry(CaffeineCacheManager caffeineCacheManager, String cacheName, String key, Object value, long duration, TimeUnit timeUnit) {
        CaffeineCache caffeineCache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
        Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
        Policy.VarExpiration varExpiration = (Policy.VarExpiration) nativeCache.policy().expireVariably().get();
        varExpiration.put(key, value, duration, timeUnit);`
    }

我没能理解整个过程。它提到我们可以使用cache.policy()来获取Policy.VarExpiration接口,该接口提供了对我需要的方法的访问。为此,我添加了以下代码-
原则上,这就是我想要的。但是,当我获得nativeCache对象时,它不会显示为策略(policy = null)。这阻止了我使用它来放置对象,因为它只返回NPE。我该如何处理这个问题?null policy for empty map
添加CaffeineCache的配置-

`   `@Bean
    public CaffeineCacheManager caffeineCacheManager(Caffeine caffeine){
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        caffeineCacheManager.setCaffeine(caffeine);
        return caffeineCacheManager;
    }

    @Bean
    public Caffeine CaffeineCacheConfig() {
        return Caffeine.newBuilder()
                .expireAfterWrite(5, TimeUnit.MINUTES)
                .initialCapacity(1000)
                .maximumSize(1200);
    }`
`
mwg9r5ms

mwg9r5ms1#

我能让它工作。从文件上看-
/**根据可变过期策略返回执行操作的访问权限。此策略 * 确定一旦每个条目 * 持续时间过去,条目应自动从该高速缓存中删除。

  • 如果该高速缓存不是用变量过期构造的,或者实现不支持这些操作,则返回空的{@link Optional}。* * @如果使用了可变过期策略,则返回对该缓存的低级操作的访问权限 */ @NonNull

在此基础上,我删除了expireAfterWrite属性,并实现了expireAfter。我能够测试VarExpiration.put的动态ttl工作正常。我将更新这个答案后,我已经测试了一个默认的5分钟也被应用在一个缺失的ttl的情况下。

@Bean
public <K,V> Caffeine<K, V> CaffeineCacheConfig() {
    return Caffeine.newBuilder()
        .initialCapacity(1000)
        .expireAfter(new Expiry<K , V>() {
            public long expireAfterCreate(K key, V graph, long currentTime) {
                // Use wall clock time, rather than nanotime, if from an external resource
                //return TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_IN_SECONDS);
                log.info("Expire after create");
                return TimeUnit.SECONDS.toNanos(5 * 60);
            }

            public long expireAfterUpdate(K key, V graph,
                long currentTime, long currentDuration) {
                return currentDuration;
            }
    
            public long expireAfterRead(K key, V graph,
                long currentTime, long currentDuration) {
                return currentDuration;
            }
        }
    ).maximumSize(1200)
     .evictionListener(((key, value, cause) -> {
          log.info("evicted key, value, cause : {} {} {}", key, value, cause);
      })).removalListener(((key, value, cause) -> {
          log.info("removed key, value, cause : {} {} {}", key, value, cause);
      }));
}

相关问题