Databases 13 min read

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.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Differences Among Jedis, Redisson, Lettuce and Using RedisTemplate & RedissonClient in Spring Boot

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.

JavaRediscachingJedisSpring BootRedissonLettuce
Java Architect Essentials
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.