1. 概述

在本文中,我们将介绍Google Guava库中的CacheLoader概念。**在此之前,我们建议您对LoadingCache类有一个基本的了解,因为CacheLoader与它密切相关。**

简单来说,CacheLoader是一个函数,用于在Guava LoadingCache中找不到值时进行计算。

2. 与LoadingCache一起使用CacheLoader

LoadingCache发生缓存未命中或需要刷新时,CacheLoader会被用来计算值。这有助于将我们的缓存逻辑封装在一个地方,使代码更紧密地关联。

2.1. Maven依赖

首先,让我们添加Maven依赖:

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>32.1.3-jre</version>
</dependency>

您可以在Maven仓库找到最新版本。

2.2. 计算并缓存值

现在,让我们看看如何使用CacheLoader创建一个LoadingCache

LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
  .build(new CacheLoader<String, String>() {
    @Override
    public String load(final String s) throws Exception {
      return slowMethod(s);
    }
});

LoadingCache会在需要计算尚未缓存的值时调用我们的内联CacheLoader。让我们尝试计算当我们多次从缓存中获取数据时,slowMethod()被调用的次数:

String value = loadingCache.get("key");
value = loadingCache.get("key");

assertThat(callCount).isEqualTo(1);
assertThat(value).isEqualTo("expectedValue");

如我们所见,它只被调用了一次。第一次是因为值尚未被计算,所以没有缓存。第二次,值已从上一次调用中缓存,从而避免了再次调用slowMethod()的开销。

2.3. 刷新缓存

缓存的另一个常见问题是刷新。虽然最难的部分通常是知道何时刷新,但另一个问题是如何刷新。使用CacheLoader解决“如何”问题很简单。LoadingCache会为每个需要刷新的值调用它。让我们通过测试来验证这一点:

String value = loadingCache.get("key");
loadingCache.refresh("key");

assertThat(callCount).isEqualTo(2);
assertThat(value).isEqualTo("key");

与后续的get()调用不同,refresh()会强制CacheLoader再次被调用,确保我们的值是最新的。

3. 总结

在这篇文章中,我们解释了CacheLoader如何在LoadingCache中计算缓存未命中的值以及在刷新缓存时进行计算。关于Guava缓存的更深入内容,可以参考我们的Guava缓存教程

这些示例的实现可以在GitHub上查看。这是一个Maven项目,可以直接运行。