Spring Boot 3 提供了 spring-boot-starter-data-redis 模块来简化 Redis 的集成工作。该模块支持两种 Redis 客户端实现:Lettuce 和 Jedis。
Jedis 是一个同步阻塞的 Redis 客户端,不支持异步操作且线程不安全,需要每个线程一个实例并通过连接池管理。它提供了全面的 Redis 操作 API,且 API 与 Redis 指令一一对应,简单易用,但受限于同步阻塞 IO 和线程不安全性。
注意: 虽然使用简单,但在多线程环境下需要额外的连接池管理,因此在高并发场景下不如 Lettuce 性能好。
Lettuce 是一个基于 Netty 框架的异步非阻塞 Redis 客户端,支持线程安全、异步及响应式编程,并具备分布式缓存适用性,同时集成了集群、Sentinel、管道和编码器等高级功能。尽管其 API 相对抽象增加了学习成本,但常通过 RedisTemplate 等工具简化操作。
注意: Spring Boot 3 版本中默认的 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");
}
}