3 Redis 的 Java 客户端
3.1 概述
- Redis 客户端的通用性
Redis 支持多语言客户端(Java/C/PHP 等),不同语言通过对应客户端库与 Redis 服务端交互,而非仅用 redis-cli 命令行。 - Java 客户端核心选型
|----------|----------------------------------|
| 架构层 | 具体实现 |
| 用户 | 你写的 Java/SpringBoot 业务代码 |
| Client 层 | Jedis/Lettuce/Redisson(Java 客户端) |
| 引擎层 | Redis 服务端(redis-server) |
- 官方推荐
基础操作:Jedis、Lettuce(轻量级 Java 客户端,满足常规 Redis 命令调用);
高级功能:Redisson(封装了分布式锁、分布式集合等高级特性,企业中用于复杂场景)。 - 企业主流现状
早期项目:Jedis 占比最高(轻量、易用,学习成本低);
现阶段主流(SpringBoot 2.x+):Lettuce(SpringBoot 默认集成,支持异步 / 响应式、线程安全,连接池性能更优);
复杂分布式场景:Redisson(弥补 Jedis/Lettuce 高级功能不足,如分布式锁、延迟队列等)。 - 核心说明
Jedis:开源项目(托管于 GitHub),轻量级但单线程非线程安全,需配合连接池使用;
Lettuce:基于 Netty 实现,天生线程安全,支持多线程共享连接,无需额外池化配置即可高性能使用;
三者定位:Jedis/Lettuce 聚焦基础 Redis 操作,Redisson 聚焦分布式场景的高级封装。
- Jedis 的介绍
Jedis 是 Java 语言的 Redis 客户端(对应client-引擎架构的 Client 层),和 redis-cli 功能一致,只是使用场景不同。
3.2 Spring 项目里用 Jedis 连接 Redis
- 依赖 jedis 和 commons-pool 包,需要在 pom.xml 中引入坐标。
- 两种连接方式
- 单实例连接
直接创建 Jedis 对象,指定 Redis 服务端 IP 和端口,用完后关闭连接。
缺点:每次请求都新建连接,性能差,资源浪费。 - 连接池连接(推荐)
通过 JedisPool 管理连接,复用连接,提升性能。
配置 JedisPoolConfig 来设置最大连接数、最大空闲数等参数。
3.3 SpringBoot 连接 Redis
SpringBoot 对 Redis 连接做了深度封装,比传统 Spring 更简洁。
-
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
SpringBoot 提供了 spring-boot-starter-data-redis 依赖,默认集成了 Lettuce 客户端(替代了 Jedis,性能更优、线程安全),默认是连接池的方式。 -
编写配置文件
在配置文件中指定 Redis 服务端信息,无需手动创建连接对象。
默认是用 Lettuce,但是也可以自己改成jedis。
日常开发只用写前面四个配置就够了。spring:
redis:
# 基础连接信息(必配)
host: 101.201.155.5 # Redis服务端IP,本地填127.0.0.1,远程填服务器IP
port: 6379 # Redis端口,默认6379
password: "" # Redis密码,无密码则留空(注意:不是写null,是空字符串)
database: 0 # 连接的Redis数据库编号,默认0号库(0-15可选)
timeout: 10000 # 连接超时时间,单位毫秒(默认10秒,可根据需求调整)
# ==================== 以下根据客户端类型二选一配置 ====================
# 【选项1】使用Lettuce客户端(SpringBoot默认,推荐)
lettuce:
pool:
max-active: 8 # 连接池最大连接数(默认8)
max-idle: 8 # 连接池最大空闲连接数(默认8)
min-idle: 0 # 连接池最小空闲连接数(默认0)
max-wait: -1ms # 连接池最大等待时间,-1表示无限制(默认)# 【选项2】使用Jedis客户端(需先排除Lettuce依赖,再引入Jedis依赖) # jedis: # pool: # max-active: 8 # max-idle: 8 # min-idle: 0 # max-wait: -1ms -
操作工具
基于 spring-boot-starter-data-redis 依赖,核心操作工具是 RedisTemplate 和 StringRedisTemplate。
区别
|--------|-------------------------------------------------------------------------------|--------------------------------------------------------|
| 特性 | StringRedisTemplate | RedisTemplate |
| 序列化方式 | 默认 StringRedisSerializer (UTF-8 字符串序列化,无额外前缀) | 默认 JdkSerializationRedisSerializer (JDK 对象序列化,带类元信息前缀) |
| 数据类型限制 | 存入的所有值(key/Hash 字段 / List 元素等) 必须是 String 类型 (容器如 Map/List 仅作为 "装字符串的工具") | 存入的所有值可以是任意 Java 类型(String/Integer/ 自定义对象等) |
| 乱码表现 | Redis 客户端(redis-cli)查看无乱码 | Redis 客户端查看有乱码(前缀元信息导致) |
| 代码读写 | 同一模板存 / 取:无乱码;跨模板读:返回 null | 同一模板存 / 取:无乱码;跨模板读:返回 null |
| 适用场景 | 日常开发 90% 场景(存字符串 / JSON 字符串) | 需直接存 / 取 Java 对象(如 User/List)且不想手动转 JSON 时 |
序列化
- 序列化:将 Java 中的数据(字符串 / 对象)转为字节数组(byte []),用于存储(Redis)/ 传输;
- 反序列化:将字节数组还原为 Java 数据的逆过程。
- Redis 仅识别字节数组。
操作的本质
Redis 本质是个 "远程字节仓库"。
不管是 StringRedisTemplate 还是 RedisTemplate,操作 Redis 的本质都是:
Java 程序 → 把数据序列化(转字节)→ 发送字节到 Redis 服务器存储 → 读取时从 Redis 取字节 → 反序列化(转 Java 数据)
两个模板的序列化差异
RedisTemplate
- 序列化规则
默认用 JdkSerializationRedisSerializer,这是 JDK 原生的对象序列化方式 ------ 它不仅把 "对象数据" 转字节,还会加一堆对象的元信息(比如类名、类型标识,像 \xac\xed\x00\x05 就是 JDK 序列化的固定前缀)。 - 乱码(仅出现在redis-cli):
Redis 客户端(比如 redis-cli)查看数据时,会默认按 "UTF-8 字符串" 解析字节。但 JDK 序列化的字节里有 "非 UTF-8 的前缀标识",解析这些标识就会出现乱码(比如 \xac\xed 解析成乱码符号),和是不是中文无关 ------ 哪怕存 "hello",Redis 里的字节是 前缀 + hello的字节,客户端看也是 乱码前缀 + hello。(乱码是所有数据都乱码,包括键)

- 适用场景
当你要把 User、Order 这类完整的 Java 对象存到 Redis 时,用它。
StringRedisTemplate
序列化规则
默认用 StringRedisSerializer,它只处理字符串 ------ 直接把 Java 字符串按 UTF-8 规则 转成纯字节(无任何额外前缀),反序列化时也按 UTF-8 把字节转回字符串。
redis-cli无乱码
Redis 客户端也是按 UTF-8 解析字节,规则完全匹配。存 "张三" 就转成 "张三" 的 UTF-8 字节,存 "hello" 就转成 "hello" 的 UTF-8 字节,客户端查看时能完美解析。
适用场景
日常开发 90% 的场景都是存字符串(比如把 User 对象转成 JSON 字符串、存 token、存验证码),这时候用它最友好 ------ 相当于你把对象先转成字符串(JSON),再按字符串规则序列化。