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.
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);
}