Differences Among Jedis, Redisson, Lettuce and Using RedisTemplate & RedissonClient in Spring Boot
This article compares the Java Redis clients Jedis, Redisson, and Lettuce, explains their distinct features and thread‑safety, and provides detailed Spring Boot configurations and code examples for RedisTemplate, RedissonClient, and cache annotations to implement caching, distributed locks, and atomic operations.
1. Differences Among Jedis, Redisson, Lettuce
All three provide Java APIs for Redis operations, but they differ in implementation and features. Jedis uses blocking I/O, synchronous calls, and is not thread‑safe without a connection pool. Redisson offers distributed locks, collections, and delayed queues. Lettuce, built on Netty, provides asynchronous, thread‑safe calls, supports clustering, Sentinel, pipelining, and custom codecs.
2. RedisTemplate Configuration and Usage
2.1 Maven Dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>2.2 application-dev.yml
spring:
redis:
host: 192.168.1.140
port: 6379
password:
database: 15 # specify Redis database (0‑15)2.3 Sample Service Method Using StringRedisTemplate
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public CustomersEntity findById(Integer id) {
try {
String toString = stringRedisTemplate.opsForHash().get(REDIS_CUSTOMERS_ONE, id + "").toString();
if (toString != null) {
return JSONUtil.toBean(toString, CustomersEntity.class);
}
} catch (Exception e) {
e.printStackTrace();
}
Optional
byId = customerRepo.findById(id);
if (byId.isPresent()) {
CustomersEntity customersEntity = byId.get();
try {
stringRedisTemplate.opsForHash().put(REDIS_CUSTOMERS_ONE, id + "", JSONUtil.toJsonStr(customersEntity));
} catch (Exception e) {
e.printStackTrace();
}
return customersEntity;
}
return null;
}2.4 StringRedisTemplate Default Serialization
public class StringRedisTemplate extends RedisTemplate
{
/**
* Constructs a new StringRedisTemplate instance.
*/
public StringRedisTemplate() {
RedisSerializer
stringSerializer = new StringRedisSerializer();
setKeySerializer(stringSerializer);
setValueSerializer(stringSerializer);
setHashKeySerializer(stringSerializer);
setHashValueSerializer(stringSerializer);
}
}3. RedissonClient Operation Example
3.1 Maven Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.8.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>LATEST</version>
</dependency>3.2 Redisson Configuration (YAML)
# Redisson configuration
singleServerConfig:
address: "redis://192.168.1.140:6379"
password: null
clientName: null
database: 15 # choose DB 0‑15
idleConnectionTimeout: 10000
pingTimeout: 1000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
reconnectionTimeout: 3000
failedAttempts: 3
subscriptionsPerConnection: 5
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 32
connectionPoolSize: 64
dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec:
class: "org.redisson.codec.JsonJacksonCodec"
transportMode: "NIO"3.3 Java Config to Create RedissonClient
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redisson() throws IOException {
// Config.fromYAML or Config.fromJSON
Config config = Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml"));
return Redisson.create(config);
}
}3.4 REST Controller Demonstrating Basic Operations
@RestController
@RequestMapping("/")
public class TeController {
@Autowired
private RedissonClient redissonClient;
static long i = 20;
static long sum = 300;
// String set/get
@GetMapping("/set/{key}")
public String s1(@PathVariable String key) {
RBucket
keyObj = redissonClient.getBucket(key);
keyObj.set(key + "1-v1");
return key;
}
@GetMapping("/get/{key}")
public String g1(@PathVariable String key) {
RBucket
keyObj = redissonClient.getBucket(key);
return keyObj.get();
}
// Hash set/get
@GetMapping("/hset/{key}")
public String h1(@PathVariable String key) {
Ur ur = new Ur();
ur.setId(MathUtil.randomLong(1,20));
ur.setName(key);
RMap
ss = redissonClient.getMap("UR");
ss.put(ur.getId().toString(), ur);
return ur.toString();
}
@GetMapping("/hget/{id}")
public String h2(@PathVariable String id) {
RMap
ss = redissonClient.getMap("UR");
Ur ur = ss.get(id);
return ur.toString();
}
// List all keys
@GetMapping("/all")
public String all(){
RKeys keys = redissonClient.getKeys();
Iterable
keys1 = keys.getKeys();
keys1.forEach(System.out::println);
return keys.toString();
}
// Read‑Write lock example and atomic decrement omitted for brevity
}4. Redis Cache with Spring Annotations
4.1 Cache Configuration
// Define serialization and cache manager
@EnableCaching
@Configuration
@ConfigurationProperties(prefix = "spring.cache.redis")
public class RedisCacheConfig {
private Duration timeToLive = Duration.ZERO;
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer
redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer
jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(timeToLive)
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
return RedisCacheManager.builder(factory).cacheDefaults(config).build();
}
}4.2 Service Methods Using @Cacheable, @CacheEvict, @CachePut
@Transactional
@Service
public class ReImpl implements RedisService {
@Resource
private CustomerRepo customerRepo;
@Resource
private StringRedisTemplate stringRedisTemplate;
public static final String REDIS_CUSTOMERS_ONE = "Customers";
public static final String REDIS_CUSTOMERS_ALL = "allList";
@Override
@Cacheable(value = "cache:customer", unless = "null == #result", key = "#id")
public CustomersEntity cacheOne(Integer id) {
Optional
byId = customerRepo.findById(id);
return byId.isPresent() ? byId.get() : null;
}
@Override
@CacheEvict(value = "cache:customer", key = "'cacheOne5' + '.' + #id")
public Object del(Integer id) { return null; }
@Override
@Cacheable(value = "cache:all")
public List
cacheList() {
return customerRepo.findAll();
}
@Override
@CachePut(value = "cache:all", unless = "null == #result", key = "#root.methodName")
public List
cacheList2() {
return customerRepo.findAll();
}
}Additional resources, links to Redisson configuration wiki and Redis‑command mapping are provided for further exploration.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.