Files
spring-boot-demo/redis/docs/09-redis-as-cache.md
T

3.0 KiB

Home | Prev: TTL | Next: Production checklist

9. Redis as the Spring cache

The annotations (@Cacheable, @CacheEvict, keys, the self-invocation trap) are covered in The Spring Cache Abstraction and its companion project. This chapter is only about what changes when the cache is Redis.

With spring-boot-starter-cache and the Redis starter on the classpath and @EnableCaching, Boot picks org.springframework.data.redis.cache.RedisCacheManager (14-cache-default.txt). UserService has two cached methods that differ only in whether the result is Serializable.

What the defaults store

Keys are readable: <cacheName>::<key>, here legacy::1. The value is JDK-serialised, exactly as in chapter 2:

$ redis-cli -p 6390 --no-raw GET legacy::1
"\xac\xed\x00\x05sr\x00'com.ankurm.redis.model.SerializableUser..."

spring.cache.redis.time-to-live=10m works: TTL legacy::1 is 600.

A result that is not Serializable is not cached, and the method call fails:

java.lang.IllegalStateException
  message: Cannot serialize value of type com.ankurm.redis.model.User without a serializer
method body ran 2 time(s) in total

The body ran (twice in total: once for the good call, once for the failing one), the write to Redis threw, and the caller sees the exception. A @Cacheable on a method returning a non-Serializable type breaks that method.

Switching to JSON

Declare a RedisCacheConfiguration bean. JsonCacheConfig (active under the json-cache profile) does it with the same allow-listed Jackson 3 serializer as chapter 4 (15-cache-json.txt):

$ redis-cli -p 6390 GET users::1
{"@class":"com.ankurm.redis.model.User","id":1,"name":"Ankur"}

The non-Serializable record now caches, and the method body ran once for two calls.

The property that stops applying

The test sets spring.cache.redis.time-to-live=10m and declares a bean with entryTtl(Duration.ofMinutes(5)). The key's TTL is 300. When you define your own RedisCacheConfiguration, Boot used that bean and the spring.cache.redis.time-to-live property had no effect on the TTL. Put the TTL in the bean.

Going deeper

Home | Prev: TTL | Next: Production checklist