Search code examples
spring-bootspring-data-redisspring-cache

Modify Spring's RedisCacheConfiguration


I'm setting the configuration of a Spring Data Redis Cache on application.properties using the spring.cache.redis.* keys.

However, not everything is possible to be configured on application.properties and I'd like to get a reference to the RedisCacheConfiguration created by Spring and do some further configuration on it.

From all the examples I found, it seems that this is not possible, since all of them show something like:

@Bean
RedisCacheConfiguration getRedisCacheConfiguration() {
    return RedisCacheConfiguration.defaultCacheConfig()
           .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
           .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
}

And the defaultCacheConfig method just ignores application.properties.

I also tried to get an autowired reference using:

@Bean
public RedisCacheManager getRedisCacheManager(RedisConnectionFactory connectionFactory, RedisCacheConfiguration redisCacheConfiguration) {
...

But that just results in an Exception:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.cache.RedisCacheConfiguration' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

So, is what I want to do impossible? Should I just forget about application.properties and configure everything in code?

I'm using Spring Boot (with spring-boot-starter-cache and spring-boot-starter-data-redis) 2.7.8, Java 17 and Lettuce 6.1.10.RELEASE.


Solution

  • For reference, I'm posting the solution I ended up with, but John Blum's answer offers more options.

    @Bean
    public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        var om = jacksonObjectMapperBuilder.createXmlMapper(false).build();
        var serializer = new Jackson2JsonRedisSerializer(om.getTypeFactory().constructCollectionType(List.class, MyObject.class));
        serializer.setObjectMapper(om);
        
        return builder -> {
            builder.initialCacheNames(Set.of("mycache")); //remove this line if using spring.cache.cache-names on application.properties
            builder.getCacheConfigurationFor("mycache")
                .ifPresent(config -> builder.withCacheConfiguration("mycache", config
                    .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))));
        };
    }