Backend Development 15 min read

Comprehensive Guide to Spring Cache: A Unified Caching Solution for Redis, Ehcache and Other Middleware

This article introduces Spring Cache as a framework‑agnostic caching abstraction that eliminates manual cache code, explains its core concepts, annotations, configuration options, and demonstrates practical usage with Redis and custom key, condition, and eviction strategies in Spring Boot applications.

Wukong Talks Architecture
Wukong Talks Architecture
Wukong Talks Architecture
Comprehensive Guide to Spring Cache: A Unified Caching Solution for Redis, Ehcache and Other Middleware

In the previous three articles we covered cache usage and distributed locks based on Redis; this piece presents a solution that works with any cache middleware, whether Redis or Ehcache, without writing specific cache code.

1. Unveiling Spring Cache

1.1 Pain points of existing cache solutions

Typical scenarios require developers to write code for adding, updating, and deleting cache entries, and switching cache providers (e.g., from Redis to Ehcache) forces a rewrite of that code.

Manual cache operations are required.

Changing the cache implementation is cumbersome because the code is tightly coupled to a specific middleware.

Spring Cache addresses both issues by providing a unified abstraction.

1.2 What is Spring Cache?

Spring Cache is a complete caching solution offered by the Spring framework. It defines org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces (since Spring 3.1) and supports annotations to simplify development, allowing seamless integration with various providers such as Redis, Ehcache, Caffeine, etc.

1.3 Effects of Spring Cache

When a method annotated with a caching annotation is invoked, Spring checks whether the method (identified by its parameters) has been called before; if so, the cached result is returned, otherwise the method executes and its result is stored for future calls.

1.4 How Spring Cache works

Spring creates an AOP proxy around the target class or method. The proxy intercepts calls, applies the caching logic (read, write, or delete) based on the annotation, and delegates to the original method only when necessary.

1.5 Cache annotations

Spring provides four primary annotations: @Cacheable , @CachePut , @CacheEvict , and @Caching . The diagram below (original) shows their relationships.

2. Using Spring Cache

2.1 Adding the dependency

Include the Spring Cache starter in pom.xml :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2.2 Selecting a cache provider

Spring Cache supports nine built‑in providers (Caffeine, Couchbase, Generic, Hazelcast, Infinispan, JCache, None, Redis, Simple). This guide uses Redis for demonstration.

Configure Redis in application.properties :

spring.cache.type=redis
spring.cache.redis.time-to-live=3600000
spring.cache.redis.key-prefix=passjava_
spring.cache.redis.use-key-prefix=true
spring.cache.redis.cache-null-values=true

Also add the Redis starter dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.3 Testing the cache

Enable caching on the main class with @EnableCaching . Then annotate a method with @Cacheable :

@RequestMapping("/test")
@Cacheable({"hot"})
public int test() {
    return 222;
}

The first call creates a Redis entry named hot with key SimpleKey[] . Subsequent calls retrieve the cached value without executing the method.

Another method test2 annotated similarly will share the same default key, resulting in the same cached value unless a custom key is defined.

2.4 Custom configuration class

A custom MyCacheConfig can be created to fine‑tune serialization, TTL, etc. (implementation omitted for brevity).

2.5 Custom keys

Use SpEL expressions such as #root.method.name to generate keys based on the method name:

@Cacheable(value={"hot"}, key="#root.method.name")

This produces keys like passjava_test and passjava_test2 .

2.6 Conditional caching

Control caching with condition and unless attributes using SpEL. Example:

@Cacheable(value="hot", unless="#result.message.contains('NoCache')")

2.7 Updating cache

@CachePut always executes the method and stores its return value in the cache. Example:

@RequestMapping("/create")
@CachePut(value="hot", key="#result.id")
public QuestionEntity create(@Valid @RequestBody QuestionEntity question) {
    return IQuestionService.createQuestion(question);
}

2.8 Evicting cache

@CacheEvict removes entries. Example:

@RequestMapping("/remove/{id}")
@CacheEvict(value="hot")
public R remove(@PathVariable("id") Long id) {
    IQuestionService.removeById(id);
    return R.ok();
}

The key is derived from the method argument (e.g., passjava_123 ).

3. Summary

Spring Cache provides five core annotations: @Cacheable, @CachePut, @CacheEvict, @Caching, @CacheConfig.

Custom keys can be defined via SpEL expressions.

Cache configuration (TTL, prefix, null‑value handling) is centralized in application.properties or a Java config class.

Conditional caching allows fine‑grained control over when entries are stored.

The next article will discuss cache consistency challenges.

backendJavacacheRedisSpringSpringBootEhcache
Wukong Talks Architecture
Written by

Wukong Talks Architecture

Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.