Spring Boot Cache Abstraction
Overview
6-step workflow for enabling cache abstraction, configuring providers (Caffeine,
Redis, Ehcache), annotating service methods, and validating behavior in
Spring Boot 3.5+ applications. Apply @Cacheable for reads, @CachePut for
writes, @CacheEvict for deletions. Configure TTL/eviction policies and expose
metrics via Actuator.
When to Use
- Add
@Cacheable, @CachePut, or @CacheEvict to service methods.
- Configure Caffeine, Redis, or Ehcache with TTL and capacity policies.
- Implement eviction strategies for stale data.
- Diagnose cache misses or invalidation issues.
- Expose hit/miss metrics via Actuator or Micrometer.
Instructions
Add dependencies — spring-boot-starter-cache plus a provider:
- Caffeine:
caffeine starter
- Redis:
spring-boot-starter-data-redis
- Ehcache:
ehcache starter
Enable caching — annotate a @Configuration class with @EnableCaching
and define a CacheManager bean.
Annotate methods — @Cacheable for reads, @CachePut for writes,
@CacheEvict for deletions.
Configure TTL/eviction — set spring.cache.caffeine.spec,
spring.cache.redis.time-to-live, or spring.cache.ehcache.config.
Shape keys — use SpEL in key attributes; guard with
condition/unless for selective caching.
Validate setup — run integration test to confirm cache hit on second
call; check GET /actuator/caches to verify cache manager registration;
query GET /actuator/metrics/cache.gets for hit/miss ratios.
Examples
Example 1: Basic @Cacheable Usage
@Service
@CacheConfig(cacheNames = "users")
class UserService {
@Cacheable(key = "#id", unless = "#result == null")
User findUser(Long id) { ... }
}
First call → cache miss, repository invoked
Second call → cache hit, repository skipped
Example 2: Conditional Caching with SpEL
@Cacheable(value = "products", key = "#id", condition = "#price > 100")
public Product getProduct(Long id, BigDecimal price) { ... }
// Only expensive products are cached
Example 3: Cache Eviction
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) { ... }
For progressive scenarios (basic product cache, multilevel eviction, Redis
integration), load references/cache-examples.md.
Advanced Options
- Use JCache annotations (
@CacheResult, @CacheRemove) for providers favoring
JSR-107 interoperability; avoid mixing with Spring annotations on the same method.
- Cache reactive return types (
Mono, Flux) or CompletableFuture values.
- Apply HTTP
CacheControl headers when exposing cached responses via REST.
- Schedule periodic eviction with
@Scheduled for time-bound caches.
- Create a
CacheManagementService for programmatic cacheManager.getCache(name).
Troubleshooting
If cache misses persist after adding @Cacheable:
- Verify
@EnableCaching is present on a @Configuration class.
- Confirm the method is public and called from outside the class (Spring uses
proxies; self-invocation bypasses the cache).
- Validate SpEL key expressions resolve correctly.
- Confirm the cache manager bean is registered as
cacheManager or explicitly
referenced via cacheManager = "myCacheManager".
References
references/spring-framework-cache-docs.md:
curated excerpts from Spring Framework Reference Guide.
references/spring-cache-doc-snippet.md:
narrative overview from Spring documentation.
references/cache-core-reference.md:
annotation parameters, dependency matrices, property catalogs.
references/cache-examples.md:
end-to-end examples with tests.
Best Practices
- Prefer constructor injection and immutable DTOs for cache entries.
- Separate cache names per aggregate (
users, orders) to simplify eviction.
- Log cache hits/misses only at debug; push metrics via Micrometer.
- Tune TTLs based on data staleness tolerance; document rationale in code.
- Guard caches storing PII or credentials with encryption or avoid caching.
- Align cache eviction with transactional boundaries to prevent dirty reads.
Constraints and Warnings
- Avoid caching mutable entities that depend on open persistence contexts.
- Do not mix Spring cache annotations with JCache annotations on the same method.
- Validate serialization compatibility when caching across service instances.
- Monitor memory footprint to prevent OOM with in-memory stores.
- Caffeine + Redis multi-level caches require publish/subscribe invalidation channels.
Related Skills
1---2name: spring-boot-cache3description: Provides patterns for implementing Spring Boot caching: configures Redis/Caffeine/EhCache providers with TTL and eviction policies, applies @Cacheable/@CacheEvict/@CachePut annotations, validates cache hit/miss behavior, and exposes metrics via Actuator. Use when adding caching to Spring Boot services, configuring cache expiration, evicting stale data, or diagnosing cache misses.4---5
6# Spring Boot Cache Abstraction
7
8## Overview
9
106-step workflow for enabling cache abstraction, configuring providers (Caffeine,
11Redis, Ehcache), annotating service methods, and validating behavior in
12Spring Boot 3.5+ applications. Apply `@Cacheable` for reads, `@CachePut` for
13writes, `@CacheEvict` for deletions. Configure TTL/eviction policies and expose
14metrics via Actuator.
15
16## When to Use
17
18- Add `@Cacheable`, `@CachePut`, or `@CacheEvict` to service methods.
19- Configure Caffeine, Redis, or Ehcache with TTL and capacity policies.
20- Implement eviction strategies for stale data.
21- Diagnose cache misses or invalidation issues.
22- Expose hit/miss metrics via Actuator or Micrometer.
23
24## Instructions
25
261. **Add dependencies** — `spring-boot-starter-cache` plus a provider:
27 - Caffeine: `caffeine` starter
28 - Redis: `spring-boot-starter-data-redis`
29 - Ehcache: `ehcache` starter
30
312. **Enable caching** — annotate a `@Configuration` class with `@EnableCaching`
32 and define a `CacheManager` bean.
33
343. **Annotate methods** — `@Cacheable` for reads, `@CachePut` for writes,
35 `@CacheEvict` for deletions.
36
374. **Configure TTL/eviction** — set `spring.cache.caffeine.spec`,
38 `spring.cache.redis.time-to-live`, or `spring.cache.ehcache.config`.
39
405. **Shape keys** — use SpEL in `key` attributes; guard with
41 `condition`/`unless` for selective caching.
42
436. **Validate setup** — run integration test to confirm cache hit on second
44 call; check `GET /actuator/caches` to verify cache manager registration;
45 query `GET /actuator/metrics/cache.gets` for hit/miss ratios.
46
47## Examples
48
49### Example 1: Basic `@Cacheable` Usage
50
51```java
52@Service
53@CacheConfig(cacheNames = "users")
54class UserService {
55
56 @Cacheable(key = "#id", unless = "#result == null")
57 User findUser(Long id) { ... }
58}
59```
60
61```
62First call → cache miss, repository invoked
63Second call → cache hit, repository skipped
64```
65
66### Example 2: Conditional Caching with SpEL
67
68```java
69@Cacheable(value = "products", key = "#id", condition = "#price > 100")
70public Product getProduct(Long id, BigDecimal price) { ... }
71
72// Only expensive products are cached
73```
74
75### Example 3: Cache Eviction
76
77```java
78@CacheEvict(value = "users", key = "#id")
79public void deleteUser(Long id) { ... }
80```
81
82For progressive scenarios (basic product cache, multilevel eviction, Redis
83integration), load [`references/cache-examples.md`](references/cache-examples.md).
84
85## Advanced Options
86
87- Use JCache annotations (`@CacheResult`, `@CacheRemove`) for providers favoring
88 JSR-107 interoperability; avoid mixing with Spring annotations on the same method.
89- Cache reactive return types (`Mono`, `Flux`) or `CompletableFuture` values.
90- Apply HTTP `CacheControl` headers when exposing cached responses via REST.
91- Schedule periodic eviction with `@Scheduled` for time-bound caches.
92- Create a `CacheManagementService` for programmatic `cacheManager.getCache(name)`.
93
94## Troubleshooting
95
96If cache misses persist after adding `@Cacheable`:
97
981. Verify `@EnableCaching` is present on a `@Configuration` class.
992. Confirm the method is public and called from outside the class (Spring uses
100 proxies; self-invocation bypasses the cache).
1013. Validate SpEL key expressions resolve correctly.
1024. Confirm the cache manager bean is registered as `cacheManager` or explicitly
103 referenced via `cacheManager = "myCacheManager"`.
104
105## References
106
107- [`references/spring-framework-cache-docs.md`](references/spring-framework-cache-docs.md):
108 curated excerpts from Spring Framework Reference Guide.
109- [`references/spring-cache-doc-snippet.md`](references/spring-cache-doc-snippet.md):
110 narrative overview from Spring documentation.
111- [`references/cache-core-reference.md`](references/cache-core-reference.md):
112 annotation parameters, dependency matrices, property catalogs.
113- [`references/cache-examples.md`](references/cache-examples.md):
114 end-to-end examples with tests.
115
116## Best Practices
117
118- Prefer constructor injection and immutable DTOs for cache entries.
119- Separate cache names per aggregate (`users`, `orders`) to simplify eviction.
120- Log cache hits/misses only at debug; push metrics via Micrometer.
121- Tune TTLs based on data staleness tolerance; document rationale in code.
122- Guard caches storing PII or credentials with encryption or avoid caching.
123- Align cache eviction with transactional boundaries to prevent dirty reads.
124
125## Constraints and Warnings
126
127- Avoid caching mutable entities that depend on open persistence contexts.
128- Do not mix Spring cache annotations with JCache annotations on the same method.
129- Validate serialization compatibility when caching across service instances.
130- Monitor memory footprint to prevent OOM with in-memory stores.
131- Caffeine + Redis multi-level caches require publish/subscribe invalidation channels.
132
133## Related Skills
134
135- [`../spring-boot-rest-api-standards`](../spring-boot-rest-api-standards/SKILL.md)
136- [`../spring-boot-test-patterns`](../spring-boot-test-patterns/SKILL.md)
137- [`../unit-test-caching`](../unit-test-caching/SKILL.md)