源本科技 | 码上会

Spring Boot Redis 客户端

2026/04/29
1
0

引言

Spring Boot 3 提供了 spring-boot-starter-data-redis 模块来简化 Redis 的集成工作。该模块支持两种 Redis 客户端实现:Lettuce 和 Jedis。

Redis 客户端

Jedis

Jedis 是一个同步阻塞的 Redis 客户端,不支持异步操作且线程不安全,需要每个线程一个实例并通过连接池管理。它提供了全面的 Redis 操作 API,且 API 与 Redis 指令一一对应,简单易用,但受限于同步阻塞 IO 和线程不安全性。

注意: 虽然使用简单,但在多线程环境下需要额外的连接池管理,因此在高并发场景下不如 Lettuce 性能好。

Lettuce

Lettuce 是一个基于 Netty 框架的异步非阻塞 Redis 客户端,支持线程安全、异步及响应式编程,并具备分布式缓存适用性,同时集成了集群、Sentinel、管道和编码器等高级功能。尽管其 API 相对抽象增加了学习成本,但常通过 RedisTemplate 等工具简化操作。

注意: Spring Boot 3 版本中默认的 Redis 客户端实现,因为它支持异步和响应式编程,并且是线程安全的。

集成 Redis

引入依赖

<!-- Spring Boot 3 Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Lettuce 连接池依赖 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

修改配置文件

application.yml 文件中添加 Redis 连接配置:

spring:
  data:
    redis:
      # Redis 数据库索引(默认为 0)
      database: 0
      # Redis 服务器地址
      host: 192.168.203.128
      # Redis 服务器端口
      port: 6379
      # Redis 连接密码
      password: 123456
      # 连接超时时间(毫秒)
      timeout: 30000
      lettuce:
        pool:
          # 最大活跃连接数
          max-active: 8
          # 最大等待时间(毫秒),-1 表示无限等待
          max-wait: -1
          # 最大空闲连接数
          max-idle: 8
          # 最小空闲连接数
          min-idle: 1

编写配置类

创建 RedisConfig 配置类,自定义 RedisTemplate 的序列化方式:

package com.lusifer.crmeb.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 使用 Jackson2JsonRedisSerializer 序列化和反序列化 Redis 的 value 值
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(
                om.getPolymorphicTypeValidator(),
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY
        );
        Jackson2JsonRedisSerializer<Object> jacksonSerial = new Jackson2JsonRedisSerializer<>(om, Object.class);

        // String 类型 key 序列化
        template.setKeySerializer(new StringRedisSerializer());
        // String 类型 value 序列化
        template.setValueSerializer(jacksonSerial);
        // Hash 类型 key 序列化
        template.setHashKeySerializer(new StringRedisSerializer());
        // Hash 类型 value 序列化
        template.setHashValueSerializer(jacksonSerial);

        template.afterPropertiesSet();
        return template;
    }
}

编写测试类

import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.List;
import java.util.Set;

@SpringBootTest
public class RedisTests {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 测试 String 类型(基础用例)
     */
    @Test
    public void testString() {
        String key = "user:name";
        // 插入数据
        redisTemplate.opsForValue().set(key, "zhangsan");
        // 获取数据
        Object value = redisTemplate.opsForValue().get(key);
        System.out.println("String 类型获取值:" + value);
        // 删除数据
        Boolean delete = redisTemplate.delete(key);
        System.out.println("String 类型删除结果:" + delete);
    }

    /**
     * 测试 Hash 类型(存储对象/字段)
     */
    @Test
    public void testHash() {
        String key = "user:1";
        // 存储单个字段
        redisTemplate.opsForHash().put(key, "username", "lisi");
        redisTemplate.opsForHash().put(key, "age", 20);
        // 获取单个字段
        Object username = redisTemplate.opsForHash().get(key, "username");
        System.out.println("Hash 类型获取用户名:" + username);
        // 获取所有字段和值
        System.out.println("Hash 类型全部数据:" + redisTemplate.opsForHash().entries(key));
        // 删除字段
        redisTemplate.opsForHash().delete(key, "age");
    }

    /**
     * 测试 List 类型(有序列表)
     */
    @Test
    public void testList() {
        String key = "shopping:cart";
        // 左插入、右插入
        redisTemplate.opsForList().leftPush(key, "手机");
        redisTemplate.opsForList().rightPush(key, "电脑");
        redisTemplate.opsForList().rightPush(key, "平板");
        // 获取全部列表元素
        List<Object> list = redisTemplate.opsForList().range(key, 0, -1);
        System.out.println("List 类型全部数据:" + list);
        // 删除头部、尾部元素
        redisTemplate.opsForList().leftPop(key);
        redisTemplate.opsForList().rightPop(key);
    }

    /**
     * 测试 Set 类型(无序不重复)
     */
    @Test
    public void testSet() {
        String key = "user:tag";
        // 添加元素(重复元素自动去重)
        redisTemplate.opsForSet().add(key, "Java", "Redis", "Java", "Spring Boot");
        // 获取所有元素
        Set<Object> set = redisTemplate.opsForSet().members(key);
        System.out.println("Set 类型全部数据:" + set);
        // 删除指定元素
        redisTemplate.opsForSet().remove(key, "Java");
    }

    /**
     * 测试 Sorted Set 类型(有序集合,排行榜专用)
     */
    @Test
    public void testSortedSet() {
        String key = "score:rank";
        // 添加元素(分数+值)
        redisTemplate.opsForZSet().add(key, "zhangsan", 85);
        redisTemplate.opsForZSet().add(key, "lisi", 92);
        redisTemplate.opsForZSet().add(key, "wangwu", 78);
        // 按分数升序获取全部元素
        Set<Object> zSet = redisTemplate.opsForZSet().range(key, 0, -1);
        System.out.println("Sorted Set 升序排行:" + zSet);
        // 删除指定元素
        redisTemplate.opsForZSet().remove(key, "wangwu");
    }
}