Spring Data Redis¶
codec-spring-data-redis adapts any Codec<T> to Spring Data Redis's
RedisSerializer<T>, so the codec you built — with its compression and
encryption — is what Redis stores.
<dependency>
<groupId>org.jwcarman.codec</groupId>
<artifactId>codec-spring-data-redis</artifactId>
</dependency>
RedisTemplate¶
RedisTemplate<String, Person> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(CodecRedisSerializer.of(codecFactory, Person.class));
CodecRedisSerializer.of takes a Codec<T>, a codec plus its type, or a
CodecFactory plus the type. RedisSerializer's contract treats null as
absent — it is handed null on a miss — so the codec is wrapped with
nullSafe(); every other value and exception
passes through unchanged.
The cache abstraction¶
Spring's cache abstraction wants a serialization pair rather than a serializer:
RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(CodecRedisSerializer.of(codecFactory, Person.class).serializationPair());
Auto-configuration¶
The cache auto-configuration activates when all of the following are true:
codec-spring-data-redisand the starter are on the classpathspring-boot-starter-cacheis on the classpath, and@EnableCachingis setspring-boot-starter-data-redisis on the classpath- a
CodecFactorybean is present — which a backend module and the starter give you
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Once all four hold, the auto-configured CodecFactory serializes cache
values for the caches you name:
codec.redis.cache.caches.people=com.example.Person
codec.redis.cache.caches.orders=com.example.OrderSummary
Cache values are heterogeneous but a codec is typed, which is why each cache
names its value type — a JSON backend asked to decode to Object would hand
back a Map, not a Person. Caches not listed keep Spring Boot's default
serializer; every other setting (TTL, key prefix, key serializer) is preserved.
A backend whose format is self-describing can serve every cache from one codec. Apache Fory writes the class into each payload, so with a Fory bean in place:
codec.redis.cache.default-type=java.lang.Object
Set codec.redis.cache.enabled=false to switch the auto-configuration off.
Properties reference¶
| Property | Type | Default | Meaning |
|---|---|---|---|
codec.redis.cache.enabled |
boolean |
true |
Whether codec serializes Redis cache values. |
codec.redis.cache.default-type |
class name | unset | Value type for caches not listed under caches; unset leaves them on Spring Boot's default serializer. |
codec.redis.cache.caches.<name> |
class name | (none) | Value type for the named cache. |
Compress, encrypt, cache¶
The pipeline this was built for — a CodecFactory bean whose codecs compress
and encrypt — needs nothing Redis-specific:
@Bean
CodecFactory codecFactory(ObjectMapper mapper, DataKeyProvider keys) {
CodecFactory json = new JacksonCodecFactory(mapper);
EnvelopeCodec envelope = EnvelopeCodec.builder(keys).build();
return new CodecFactory() {
@Override
public <T> Codec<T> create(TypeRef<T> type) {
return json.create(type).andThen(new ZstdCodec()).andThen(envelope);
}
};
}
Every cache named in codec.redis.cache.caches now holds compressed,
authenticated ciphertext.
Where next¶
- Spring Boot — the starter and auto-configuration this page's cache support builds on
- Codec Composition —
nullSafe(), used here to match Redis's "nullon a miss" contract - Handling Failures — what
CodecExceptionthrough aCacheErrorHandlermeans for a cache read