Caffeine getIfPresent()返回 null 问题

Caffeine getIfPresent()返回 null 问题

问题

集成 Caffeine 时, 将 Cache 注册为全局的 Bean, 然后通过@Autowired 自动装配
使用 cache.put(key, val) 和 cache.getIfPresent(key) 放入和获取缓存

@Configuration
public class CaffeineConfig {
  @Bean
  public Cache<String, Object> cache() {
    return Caffeine.newBuilder()
      // 数量
      .maximumSize(1024)
      .expireAfterWrite(30, TimeUnit.MINUTES)
      // 弱引用
      .weakKeys()
      .weakValues()
      // 删除监听事件
      .removalListener(
        (RemovalListener<String, Object>) (key, val, reason) ->
          System.out.println("key:" + key + ", val:" + val + ", reason:" + reason)
      ).build();
  }
}
@RestController
public class CaffeineController {

  private final Cache<String, Object> cache;

  @Autowired
  public CaffeineController(Cache<String, Object> cache) {
    this.cache = cache;
  }

  @PostMapping("/add")
  public Result add(String key, String val) {
    cache.put(key, val);
    return Result.success("add success");
  }

  @GetMapping
  public Result get(String key) {
    return Result.success((String) cache.getIfPresent(key));
  }
}

无论如何调用, get()总是返回 null, 最后找到问题所在, 是配置的 Bean 有问题。
在构造 Bean 时添加了参数.weakKeys()[1], 使 key 成为弱引用变量, 被垃圾回收器发现之后就会被回收掉
key被回收掉之后获取缓存时要使用==(比较地址)而不是equals()(比较值)来获取缓存[2]
去掉.weakKeys()之后, 可以成功取得缓存!

参考

[1] getIfPresent caffeine return null, https://stackoverflow.com/questions/63068085/getifpresent-caffeine-return-null
[2] Caffeine 缓存, xiaolyuh, https://www.jianshu.com/p/9a80c662dac4

posted @ 2021-06-26 22:02  FuKai  阅读(4383)  评论(0编辑  收藏  举报