Spring Cache Skill
Detect the cache provider in use, then apply the correct patterns.
Step 1 — Detect setup
Check pom.xml or build.gradle:
spring-boot-starter-data-redis→ Redis (Lettuce client by default)spring-boot-starter-cache+caffeine→ Caffeine (in-process)spring-boot-starter-cacheonly → Simple (ConcurrentHashMap, dev only)- None present → offer to add (recommend Caffeine for single-instance, Redis for multi-instance/distributed)
Check Spring Boot version:
- Boot 3.x → Lettuce 6.x, Caffeine 3.x
- Boot 2.x → Lettuce 5.x, Caffeine 2.x/3.x
Mode: review
User asks to review existing cache configuration. Check for:
-
@EnableCachingpresent on a@Configurationclass — missing it silently disables all cache annotations - Cache names declared in
application.ymlwith explicit TTL — no unnamed or unbounded caches -
@Cacheablemethods are on Spring-managed beans (notprivate, not called within the same class — proxy bypass) - Cache keys are deterministic —
@Cacheable(key = "#id")not#root.methodNameunless intentional -
@CacheEvictpresent wherever data is mutated — missing eviction causes stale cache -
@CachePutused to update cache on write — not a@CacheEvict+ re-fetch pattern - Redis serialization configured — default JDK serialization is not readable/portable; use
GenericJackson2JsonRedisSerializer - Redis TTL set — without
time-to-live, entries never expire - Caffeine
maximumSizeset — without it, cache grows unbounded and causes OOM - Null values handled —
@Cacheable(unless = "#result == null")to avoid caching nulls - Cache metrics exposed:
management.metrics.cache.instrument=true
Mode: setup
User asks to add caching from scratch.
Caffeine (recommended for single-instance apps)
- Add
spring-boot-starter-cache+com.github.ben-manes.caffeine:caffeine - Add
@EnableCachingto a@Configurationclass - Configure cache specs in
application.yml— setmaximum-sizeandexpire-after-write - Annotate service methods with
@Cacheable,@CacheEvict,@CachePut
Redis (recommended for multi-instance / distributed)
- Add
spring-boot-starter-data-redis - Configure
spring.data.redis.host/port(Boot 3.x) orspring.redis.host/port(Boot 2.x) - Configure
RedisCacheConfigurationbean — set TTL and useGenericJackson2JsonRedisSerializer - Add
@EnableCachingand annotate service methods
See references/patterns.md for full configuration examples.
Mode: cacheable
User asks to cache the result of a method.
- Place
@Cacheable(cacheNames = "products", key = "#id")on the service method - The method must be on a Spring-managed bean and not
private - The method must not call itself (proxy bypass) — extract to a separate bean if needed
- Add
unless = "#result == null"to avoid caching null results - Ensure the return type is
Serializable(Redis) or any object (Caffeine) - Add a corresponding
@CacheEvicton the update/delete method
Mode: evict
User asks to invalidate/evict cache entries on data changes.
@CacheEvict(cacheNames = "products", key = "#id")— evict a single entry on update/delete@CacheEvict(cacheNames = "products", allEntries = true)— evict all entries (use sparingly)@CacheEvict(beforeInvocation = true)— evict before method runs (use when method may throw)- For multi-cache eviction:
@Caching(evict = { @CacheEvict("products"), @CacheEvict("productList") })
Mode: redis
User asks specifically for Redis cache configuration.
- Add
spring-boot-starter-data-redis - Configure connection:
spring.data.redis.host,spring.data.redis.port,spring.data.redis.password - Define
RedisCacheManagerbean with:GenericJackson2JsonRedisSerializerfor values (human-readable, portable)StringRedisSerializerfor keys- Default TTL + per-cache TTL overrides
- Enable
@EnableCaching - For Redis Cluster: set
spring.data.redis.cluster.nodes - For Redis Sentinel: set
spring.data.redis.sentinel.masterandnodes
Output format
For review mode: list findings as [CRITICAL] / [HIGH] / [MEDIUM] / [LOW] with file:line references.
For implementation modes: show exact Maven/Gradle dependency, full application.yml block, and complete Java configuration + annotated example. State minimum Spring Boot version where it differs.