On this page
Spring Data Redis
Spring Data Redis provides a high-level abstraction for Redis operations, including template-based access, repository support, and caching integration.
Setup
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring:
data:
redis:
host: localhost
port: 6379
password: ${REDIS_PASSWORD:}
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-idle: 8
RedisTemplate
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
@Service
public class CacheService {
private final RedisTemplate<String, Object> redisTemplate;
public void set(String key, Object value, Duration ttl) {
redisTemplate.opsForValue().set(key, value, ttl);
}
public <T> T get(String key, Class<T> type) {
Object value = redisTemplate.opsForValue().get(key);
return type.cast(value);
}
public void delete(String key) {
redisTemplate.delete(key);
}
}
Data Structures
// List
redisTemplate.opsForList().rightPush("queue:orders", orderId);
String id = (String) redisTemplate.opsForList().leftPop("queue:orders");
// Set
redisTemplate.opsForSet().add("online:users", userId);
boolean online = redisTemplate.opsForSet().isMember("online:users", userId);
// Hash
redisTemplate.opsForHash().put("user:1", "name", "Alice");
String name = (String) redisTemplate.opsForHash().get("user:1", "name");
// Sorted Set (leaderboard)
redisTemplate.opsForZSet().add("leaderboard", userId, score);
Set<Object> top10 = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, 9);
Spring Cache with Redis
@EnableCaching
@Configuration
public class CacheConfig {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
}
}
@Service
public class UserService {
@Cacheable(value = "users", key = "#id")
public User findById(Long id) { return userRepository.findById(id).orElseThrow(); }
@CacheEvict(value = "users", key = "#user.id")
public User update(User user) { return userRepository.save(user); }
}
Redis Repository
@RedisHash("session")
public class UserSession {
@Id
private String sessionId;
private Long userId;
@TimeToLive
private Long ttl = 3600L;
}
public interface SessionRepository extends CrudRepository<UserSession, String> {
List<UserSession> findByUserId(Long userId);
}
Best Practices
- Use
GenericJackson2JsonRedisSerializerfor complex objects - Set TTL on all cache keys to prevent memory bloat
- Use
@Cacheable/@CacheEvictfor declarative caching - Monitor Redis memory usage and configure
maxmemory-policy - Use Redis Cluster for production HA setups