1. Introduction
In this article, we’ll introduce the Guava CacheLoader.
Before reading further, it’s recommended that there is a basic understanding of the LoadingCache class first. This is because the CacheLoader works with it specifically.
Essentially, the CacheLoader is a function used for computing a value in the event of it not being found in a Guava LoadingCache.
2. Using a CacheLoader with a LoadingCache
When there is a cache miss with a LoadingCache, or the cache needs to be refreshed, the CacheLoader will be used for calculating values. This helps to encapsulate our caching logic in one place, making our code more cohesive.
2.1. Maven Dependency
First, let’s add our Maven dependency:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>21.0</version> </dependency>
You can find the latest version in the Maven repository.
2.2. Computing and Caching Values
Now, let’s see how we can instantiate a LoadingCache with a CacheLoader:
LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder() .build(new CacheLoader<String, String>() { @Override public String load(final String s) throws Exception { return slowMethod(s); } });
Essentially, the LoadingCache will call our inline CacheLoader whenever it needs to compute a value which has not been cached. Let’s try counting how many times our slowMethod() is called when we retrieve something from cache multiple times:
String value = loadingCache.get("key"); value = loadingCache.get("key"); assertThat(callCount).isEqualTo(1); assertThat(value).isEqualTo("expectedValue");
As we can see, it was only called once. The first time the value was not cached as it had yet to be computed. The second time, it was cached from the previous call, so we could avoid the overhead of calling our slowMethod() again.
2.3. Refreshing the Cache
Another common problem with caching is refreshing the cache. Although the most difficult aspect is knowing when to refresh the cache, another one is knowing how.
Solving the how is simple when using the CacheLoader. The LoadingCache will simply invoke it for each value which needs to be refreshed. Let’s try this with a test:
String value = loadingCache.get("key"); loadingCache.refresh("key"); assertThat(callCount).isEqualTo(2); assertThat(value).isEqualTo("key");
Unlike our subsequent calls to get(), refresh() will force the CacheLoader to be called again, making sure our values are up to date.
3. Conclusion
In this article, we’ve explained how a LoadingCache is used by a CacheLoader in order to calculate values on cache misses, and also on cache refreshes. It’s also worth checking out this more in-depth article on Guava Caching.
The implementation of these examples can be found over on GitHub. This is a Maven project, so should be easy to run as is.