返回

Caffeine 自定义过期设置失效难题?五大妙招轻松解决!

java

Caffeine 自定义过期设置:无法失效缓存?别担心,有解!

问题探究

使用 Caffeine 缓存时,你希望缓存条目过期后自动失效并刷新。但当使用自定义过期策略时,缓存条目却迟迟不失效,甚至在添加新条目时还会出错。这让你很是头疼!

症结所在

问题的根源在于自定义过期实现中存在的问题。Caffeine 缓存的自定义过期策略包含三个方法:

  • expireAfterCreate:在创建缓存条目时调用,以确定条目的初始过期时间。
  • expireAfterUpdate:在更新缓存条目时调用,以确定条目的更新过期时间。
  • expireAfterRead:在读取缓存条目时调用,以确定条目的读取过期时间。

在提供的示例中,CustomExpiryOauth 类的 expireAfterCreate 方法存在问题:

@Override
public long expireAfterCreate(String key, Oauth2Token value, long currentTime) {
    log.info("expireAfterCreate value: {}", Long.parseLong(value.getExpiresIn())-2);
    return TimeUnit.SECONDS.toNanos(Long.parseLong(value.getExpiresIn())-2);
}

问题在于此方法返回的是一个负值,因为 Long.parseLong(value.getExpiresIn())-2 会产生一个负数。Caffeine 缓存无法处理负的过期时间,因此导致缓存无法正常工作。

妙手回春

为了解决这个问题,我们需要修改 expireAfterCreate 方法,以返回一个非负值。以下是如何更正后的方法:

@Override
public long expireAfterCreate(String key, Oauth2Token value, long currentTime) {
    log.info("expireAfterCreate value: {}", Long.parseLong(value.getExpiresIn()));
    return TimeUnit.SECONDS.toNanos(Long.parseLong(value.getExpiresIn()));
}

此外,还建议在 getOauth2TokenFromCache 方法中将缓存条目设置为弱引用,以便在垃圾回收时自动删除:

@Cacheable(cacheNames = "oauth2Cache" ,key = "#myMap.get('systemName')")
public Oauth2Token getOauth2TokenFromCache(Map<String, String> myMap) {
    log.info("At getOauth2TokenFromCache expiresIn = {} ",getOauth2Token(myMap).getExpiresIn());
    return CacheBuilder.newBuilder()
            .weakValues()
            .build()
            .get(myMap.get("systemName"), k -> getOauth2Token(myMap));
}

通过这些修改,自定义过期实现将能够正确工作,Caffeine 缓存也将按预期使缓存条目失效并刷新。

常规问答

1. 我如何确保自定义过期实现正常工作?
检查自定义过期方法的实现是否正确,并确保返回非负的过期时间。

2. 为什么需要将缓存条目设置为弱引用?
弱引用可以防止缓存条目在垃圾回收时被释放,从而避免数据丢失。

3. 如何解决使用自定义过期设置时遇到的其他问题?
检查 Caffeine 缓存文档,或在社区论坛上寻求帮助。

4. Caffeine 缓存是否支持所有类型的自定义过期实现?
Caffeine 支持广泛类型的自定义过期实现,但你需要确保实现符合 Caffeine 的规范。

5. 使用自定义过期设置有哪些好处?
自定义过期设置允许你根据特定需求优化缓存行为,例如根据数据过期时间或使用频率设置不同的过期策略。

结语

通过理解 Caffeine 缓存自定义过期设置的工作原理以及解决问题的技巧,你可以避免困扰并充分利用 Caffeine 强大的缓存功能。现在,你可以放心地使用自定义过期策略,让你的缓存更加智能、高效!