Master Spring Cache: Simplify Caching Across Redis, Ehcache, and More
This article introduces Spring Cache as a unified caching solution that abstracts away the specifics of Redis, Ehcache, and other providers, explains its core concepts, annotations, configuration, and demonstrates practical usage with code examples to eliminate manual cache handling.
Previously we discussed cache usage and distributed locks based on Redis; now we introduce a solution compatible with all cache middleware, so whether using Redis or Ehcache you don't need to worry about their specific operations.
The solution is the well‑known
Spring Cache. If you haven't heard of it, this article will explore it together.
1. Unveiling Spring Cache
1.1 Pain points of existing cache solutions
Scenario:
1. User A opens an app and views a flash‑sale product detail page; the product data is fetched from the database.
2. Because many users access the page in a short time, the product list can be cached for fast reads.
3. Subsequent queries can read from the cache; when the product is removed, the cache entry is deleted.
4. The steps of writing and deleting cache entries require manual code.
5. If the cache middleware changes from Redis to Ehcache, the cache‑handling code must be rewritten.
Need to write cache operations (add, update, delete) manually.
Switching cache providers is difficult because there is no abstraction layer.
Is there a solution that solves these two pain points? The answer is Spring Cache.
1.2 Introduction to Spring Cache
Spring Cache is a complete caching solution provided by Spring. It does not implement a cache itself but defines interfaces, configuration, and annotations that allow integration with various cache providers such as Redis and Ehcache, so developers do not need to handle cache details.
Since Spring 3.1, the
org.springframework.cache.Cacheand
org.springframework.cache.CacheManagerinterfaces unify different caching technologies and support annotation‑driven development.
The
Cacheinterface defines cache operations, and implementations like
RedisCache,
EhCacheCache,
ConcurrentMapCacheetc. are available.
1.3 What Spring Cache does
When a method annotated with caching is invoked, Spring checks whether the method (identified by the specified parameters) has been called before. If so, the cached result is returned; otherwise the method executes, its result is cached, and then returned.
1.4 How Spring Cache works
Spring Cache works via AOP (Aspect‑Oriented Programming). An aspect is created for the annotated method, and the cache‑related pointcut intercepts the method call to store, retrieve, or evict cache entries automatically.
1.5 Cache annotations
Spring provides four main annotations:
@Cacheable,
@CachePut,
@CacheEvict, and
@Caching.
2. Using the cache
2.1 Add Spring Cache dependency
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</code>2.2 Choose cache implementation
Spring Cache supports many providers (9 options):
caffeine – high‑performance cache based on Google Guava.
couchbase – NoSQL JSON document database.
generic – generic cache mechanism.
hazelcast – distributed data store and cache.
infinispan – distributed cluster cache.
jcache – JSR‑107 cache specification.
none – no cache.
redis – Redis cache.
simple – in‑memory cache.
We will use Redis as the cache.
2.3 Test cache
Add
@EnableCachingon the Spring Boot application class.
Annotate a method with
@Cacheableto enable caching:
<code>@RequestMapping("/test")
@Cacheable({"hot"})
public int test() {
return 222;
}
</code>The string "hot" is the cache name. The first call creates the cache entry; the second call retrieves the cached value without executing the method.
Testing a second method with the same cache name demonstrates that the default key is
SimpleKey[], causing both methods to share the same cache entry.
<code>@RequestMapping("/test2")
@Cacheable({"hot"})
public int test2() {
return 456;
}
</code>Both methods return the cached value 222 because their keys are identical.
2.4 Custom configuration
Configure Redis cache properties in
application.properties:
<code># Use Redis as cache provider
spring.cache.type=redis
# Cache TTL 3600 seconds
spring.cache.redis.time-to-live=3600000
# Prefix for cache keys
spring.cache.redis.key-prefix=passjava_
# Enable key prefix
spring.cache.redis.use-key-prefix=true
# Cache null values to prevent cache penetration
spring.cache.redis.cache-null-values=true
</code>A custom configuration class (e.g.,
MyCacheConfig) can further customize the
RedisCacheConfiguration.
2.5 Custom key
Use SpEL expressions to define the cache key, e.g.,
#root.method.nameto use the method name:
<code>@Cacheable(value = {"hot"}, key = "#root.method.name")
</code>This generates distinct keys such as
passjava_testand
passjava_test2.
2.6 Custom condition
Control caching with
conditionand
unlessattributes using SpEL:
<code>@Cacheable(value = "hot", unless = "#result.message.contains('NoCache')")
</code>If the returned
messagecontains "NoCache", the result will not be cached.
2.7 Update annotation
@CachePutalways executes the method and updates the cache. Example for saving an entity:
<code>@RequestMapping("/create")
@CachePut(value = "hot", key = "#result.id")
public QuestionEntity create(@Valid @RequestBody QuestionEntity question) {
return IQuestionService.createQuestion(question);
}
</code>The cache key becomes
passjava_123when the generated ID is 123.
2.8 Delete cache annotation
@CacheEvictremoves cache entries without adding new ones. Example:
<code>@RequestMapping("/remove/{id}")
@CacheEvict(value = "hot")
public R remove(@PathVariable("id") Long id) {
IQuestionService.removeById(id);
return R.ok();
}
</code>The key to evict matches the method argument (e.g.,
passjava_123).
3. Summary
This article introduced Spring Cache as a solution to the pain points of manual cache handling and provider lock‑in, covering:
The five core annotations:
@Cacheable,
@CachePut,
@CacheEvict,
@Caching,
@CacheConfig.
How to customize cache keys using SpEL.
How to configure cache properties such as TTL and key prefixes.
How to set conditional caching with
conditionand
unless.
Spring Cache simplifies cache integration but does not eliminate cache consistency challenges, which will be discussed in a future article.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.