Search code examples
javaspringcachingredisttl

Spring Redis Cache Implemention


I have recently implemented Redis cache in my Spring project with below java configuration

    @Configuration
    @EnableCaching
    public class CacheConfig {
        private @Value("${redis.host}") String redisHost;
        private @Value("${redis.port}") int redisPort;

        @Bean
        JedisConnectionFactory jedisConnectionFactory() {
            JedisConnectionFactory factory = new JedisConnectionFactory();
            factory.setHostName(redisHost);
            factory.setPort(redisPort);
            factory.setUsePool(true);
            return factory;
        }

        @Bean
        public ObjectMapper objectMapper() {
            return Jackson2ObjectMapperBuilder.json().serializationInclusion(JsonInclude.Include.NON_NULL) // Don’t include null values
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) //ISODate
                .build();
        }

        @Bean
        public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisJsonSerializer() {
            GenericJackson2JsonRedisSerializer genericJackson2JsonRedisJsonSerializer = new GenericJackson2JsonRedisSerializer();
            return genericJackson2JsonRedisJsonSerializer;
        }

        @Bean
        RedisTemplate<String, Object> redisTemplate() {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
            redisTemplate.setConnectionFactory(jedisConnectionFactory());
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            return redisTemplate;
        }

        @Bean
        CacheManager cacheManager() {
            return new RedisCacheManager(redisTemplate());
        }

And I am using below service method for caching the data

    @Cacheable(value = "supplierConfigResponse", key = "#searchId")
        public SupplierConfigResponse getSupplierConfig(String searchId){
            //some logic
        }

I need to set a default TTL for every key.I have gone through redisTemplate.expire(key, timeout, unit) method for setting the TTL but this requires explicit logic to cache each key and I don't want to do that in my business method. Is there any other way for setting a default TTL? Can AnyBody please help me on the same.


Solution

  • If I understand correctly, You want your different business methods to have different cache TTL but don't want to insert that logic in your methods.

    This is a trademark problem for aspects. Follow these steps.

    Create your annotation for timeout configurations.

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface ConfigureTimeout {
        int timeout();
    }
    

    Annotate your business method and give timeout configuration there.

    @ConfigureTimeout(timeout = 100)
    @Cacheable(value = "supplierConfigResponse", key = "#key")
    public String test(String key){
        //your logic
        return null;
    }
    

    Create and advice to set expiration time.

    @Before("execution(@abc.xyz.annotations.ConfigureTimeout * *(String, ..)) && 
    @annotation(configureTimeoutAnnotation) && args(key, ..)")
    public void setContext(ConfigureTimeout configureTimeoutAnnotation, String key) {
        redisTemplate.expire(key, configureTimeoutAnnotation.timeout(), TimeUnit.SECONDS);
    }