Working with Caching

1. Enabling Caching Support (@EnableCaching)

Example: Enable caching support

@SpringBootApplication
@EnableCaching
public class App {}
Auto-detected providers If on classpath
Caffeine com.github.ben-manes.caffeine:caffeine
Redis spring-boot-starter-data-redis
Hazelcast com.hazelcast:hazelcast
Simple (default) ConcurrentHashMap-based

2. Using @Cacheable for Method Results

Example: Cache method result with condition

@Service
public class ProductService {
  @Cacheable(value="products", key="#id", unless="#result == null")
  public Product byId(Long id) { /* heavy lookup */ }
}

3. Using @CachePut for Cache Updates

Annotation Effect
@Cacheable Skip method if cache hit
@CachePut Always run, store result
@CacheEvict Remove entries
@Caching Combine multiple

4. Using @CacheEvict for Cache Removal

Example: Evict by key and clear all entries

@CacheEvict(value="products", key="#p.id")
public Product update(Product p) { return repo.save(p); }

@CacheEvict(value="products", allEntries=true)
public void purge() {}

5. Configuring Cache Names and Keys

Attribute Description
value/cacheNames Logical cache(s)
key SpEL key expression
keyGenerator Custom KeyGenerator bean
condition SpEL — cache when true
unless SpEL — skip when true (sees result)

6. Using SpEL in Cache Annotations

Variable Meaning
#argName Method argument by name
#a0 / #p0 By index
#root.method Method object
#result Method return (post-execution only)
@beanName.method() Reference other beans

7. Configuring Simple Cache Provider

Example: Simple in-memory cache configuration

spring:
  cache:
    type: simple
    cache-names: [products, users, sessions]

8. Integrating Redis Cache

Example: Redis cache with TTL and JSON serializer

@Bean
RedisCacheConfiguration cacheConfig() {
  return RedisCacheConfiguration.defaultCacheConfig()
    .entryTtl(Duration.ofMinutes(10))
    .disableCachingNullValues()
    .serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}

Example: Redis cache type and connection

spring:
  cache: { type: redis }
  data:
    redis: { host: localhost, port: 6379 }

9. Integrating Caffeine Cache

Example: Caffeine cache with size and expiry spec

spring:
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=10000,expireAfterWrite=10m,recordStats

10. Configuring Cache Expiration and TTL

Provider TTL Mechanism
Redis RedisCacheConfiguration.entryTtl() per cache
Caffeine expireAfterWrite / expireAfterAccess
Simple None (no expiry)

11. Using @Caching for Multiple Operations

Example: Combined cache put and evict

@Caching(
  put = { @CachePut(value="byId", key="#u.id"),
          @CachePut(value="byEmail", key="#u.email") },
  evict = { @CacheEvict(value="all", allEntries=true) }
)
public User save(User u) { return repo.save(u); }

12. Implementing Custom Cache Manager

Example: Two-level Caffeine + Redis cache manager

@Bean
CacheManager twoLevel(RedisConnectionFactory rcf) {
  CaffeineCacheManager local = new CaffeineCacheManager("hot");
  local.setCaffeine(Caffeine.newBuilder().expireAfterWrite(Duration.ofMinutes(1)));
  RedisCacheManager remote = RedisCacheManager.create(rcf);
  return new CompositeCacheManager(local, remote);
}