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