1. Overview
This post will focus on integrating the Redis with the Spring Boot application to leverage the declarative annotation based caching support provided by the Spring cache abstraction.
2. Add Redis dependency to the application
Start by adding the Redis dependency to the build script file - build.gradle
compile('org.springframework.boot:spring-boot-starter-data-redis')
3. Redis Configuration class
To make the Spring resolve the caches by annotation, extend the CachingConfigurerSupport class and annotate the config class with @EnableCaching.
@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {...}
3.1 Redis client
Jedis is one of the popular Redis Java client, configure the JedisConnectionFactory which will create Jedis instances for connecting to the Redis server.
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName("127.0.0.1");
jedisConnectionFactory.setPort(6379);
jedisConnectionFactory.setUsePool(true);
return jedisConnectionFactory;
}
3.2 RedisTemplate
Create a RedisTemplate instance which helps to serialize/deserialize between the object and binary data on the Redis store.
Here StringRedisSerializer is used for serializing the key and GenericJackson2JsonRedisSerializer for the value. This template is a generified one, it can be wired to multiple components and reused as it’s thread-safe.
@Bean
public StringRedisSerializer stringRedisSerializer() {
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
return stringRedisSerializer;
}
@Bean
public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisJsonSerializer() {
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisJsonSerializer =
new GenericJackson2JsonRedisSerializer();
return genericJackson2JsonRedisJsonSerializer;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
redisTemplate.setExposeConnection(true);
redisTemplate.setKeySerializer(stringRedisSerializer());
redisTemplate.setValueSerializer(genericJackson2JsonRedisJsonSerializer());
return redisTemplate;
3.3 RedisCacheManager
The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces. RedisCacheManager is the implimentation of the CacheManager for Redis.
@Bean
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
redisCacheManager.setTransactionAware(true);
redisCacheManager.setLoadRemoteCachesOnStartup(true);
redisCacheManager.setUsePrefix(true);
return redisCacheManager;
}
4. Annotating the methods
For caching declaration, the abstraction provides a set of Java annotations:
4.1 @Cacheable
Triggers cache population
@Cacheable(value = "whitePaper", key = "#id")
public WhitePaper findWhitePaperById(String id)
{
return repository.findById(id);
}
4.2 @CachePut
Updates the cache without interfering with the method execution
@CachePut(value = "whitePaper", key = "#whitePaper?.id")
public WhitePaper updateWhitePaper(WhitePaper whitePaper)
{
return repository.update(whitePaper);
}
4.3 @CacheEvict
Triggers cache eviction
@CacheEvict(value = "whitePaper", key = "#id.toString()")
public WhitePaper saveWhitePaper(int id){
return repository.delete(id);
}
5. Conclusion
Redis is not a simple key-value store, it can be called as a data structure store as it’s can store data in advanced data structures. Spring Cache abstraction is a high level abstraction for interacting with the store.