Spring Boot 配置 Redis 入门指南:从环境搭建到实战操作
Spring Boot 配置 Redis 入门指南:从环境搭建到实战操作
一、前置知识与环境准备
1.1 必备环境清单
工具 / 框架 | 推荐版本 | 说明 |
JDK | 1.8 或 11 | Spring Boot 2.x 对 JDK 1.8+ 支持更稳定 |
Spring Boot | 2.x(本文以 2.7.10 为例) | 3.x 版本配置逻辑类似,依赖坐标略有差异 |
Redis 服务器 | 5.x 或 6.x | 本地安装或使用云服务器 Redis(如阿里云) |
开发工具 | IntelliJ IDEA 或 Eclipse | 推荐 IDEA,自带 Spring 插件支持 |
构建工具 | Maven 3.6+ 或 Gradle 7.x | 本文以 Maven 为例讲解依赖配置 |
1.2 Redis 服务器准备(本地版)
解压压缩包到本地目录(如 D:\Redis);
打开命令提示符(CMD),进入 Redis 解压目录,执行启动命令:
# 临时启动(关闭 CMD 后 Redis 停止)redis-server.exe redis.windows.conf
验证 Redis 是否启动成功:打开新的 CMD 窗口,执行以下命令,若返回 PONG 则表示启动正常:
redis-cli.exe -h 127.0.0.1 -p 6379 ping
二、创建 Spring Boot 项目并引入 Redis 依赖
2.1 初始化 Spring Boot 项目
配置项目基本信息(如下表),然后点击 Generate 下载项目压缩包;
配置项 | 取值建议 |
Project | Maven Project |
Language | Java |
Spring Boot | 2.7.10 |
Group | com.example(自定义) |
Artifact | spring-boot-redis-demo |
Package name | com.example.redisdemo |
Packaging | Jar |
Java | 8 |
将下载的压缩包解压,用 IDEA 打开项目(选择 Open -> 找到项目目录 -> 等待 Maven 依赖加载完成)。
2.2 引入 Redis 依赖
<!-- Spring Boot Redis starter(核心依赖) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Spring Boot Web 依赖(可选,用于后续接口测试) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 连接池依赖(可选,提升 Redis 连接效率) --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>
spring-boot-starter-data-redis:自动集成 Redis 客户端(默认使用 Lettuce,2.x 版本已替代 Jedis 作为默认客户端);
commons-pool2:Lettuce 客户端依赖的连接池组件,用于管理 Redis 连接,避免频繁创建 / 销毁连接带来的性能损耗;
spring-boot-starter-web:后续通过接口测试 Redis 功能时需要,若仅做本地测试可省略。
三、编写 Redis 核心配置
3.1 配置文件(application.properties 或 application.yml)
# Spring 相关配置spring:# Redis 配置redis:# Redis 服务器地址(本地默认 127.0.0.1,远程服务器填实际 IP)host: 127.0.0.1# Redis 端口号(默认 6379,若修改过需对应调整)port: 6379# Redis 密码(若未设置密码,可省略此配置)password: 123456 # 注意:生产环境密码需复杂且定期更换# 连接超时时间(毫秒)timeout: 10000# Lettuce 连接池配置(需引入 commons-pool2 依赖)lettuce:pool:# 连接池最大活跃连接数(默认 8)max-active: 8# 连接池最大空闲连接数(默认 8)max-idle: 8# 连接池最小空闲连接数(默认 2)min-idle: 2# 连接池最大阻塞等待时间(默认 -1,即无限制)max-wait: 1000
若 Redis 未设置密码,需删除 password 配置,否则会因认证失败无法连接;
lettuce.pool 相关配置仅在引入 commons-pool2 依赖后生效,不配置则使用默认值;
若使用远程 Redis 服务器(如阿里云),需确保服务器开放 6379 端口,且 Redis 允许外部 IP 访问(修改 Redis 配置文件 bind 0.0.0.0 并重启)。
3.2 自定义 RedisTemplate 配置(可选但推荐)
在 com.example.redisdemo 目录下创建 config 包,然后创建 RedisConfig 类;
编写配置代码,注入自定义的 RedisTemplate 和 StringRedisTemplate(专门处理 String 类型数据):
package com.example.redisdemo.config;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.core.StringRedisTemplate;import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;@Configurationpublic class RedisConfig {/*** 自定义 RedisTemplate(处理 Object 类型数据)*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 配置 Key 的序列化方式(String 序列化)StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();redisTemplate.setKeySerializer(stringRedisSerializer);redisTemplate.setHashKeySerializer(stringRedisSerializer);// 配置 Value 的序列化方式(JSON 序列化)GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);// 初始化 RedisTemplateredisTemplate.afterPropertiesSet();return redisTemplate;}/*** 专门处理 String 类型的 RedisTemplate(可选,Spring Boot 已自动注入)* 若需自定义,可参考上面的配置逻辑*/@Beanpublic StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {return new StringRedisTemplate(redisConnectionFactory);}}Key 使用 StringRedisSerializer 序列化,确保在 Redis 客户端中显示为正常字符串;
Value 使用 GenericJackson2JsonRedisSerializer 序列化,支持 Java 对象与 JSON 的自动转换,且避免乱码;
StringRedisTemplate 是 RedisTemplate 的子类,专门用于处理 String 类型的 Key 和 Value,使用更便捷。
四、实战:编写 Redis 操作代码
4.1 编写 Redis 服务层(Service)
4.1.1 RedisService 接口
package com.example.redisdemo.service;public interface RedisService {/*** 存储数据(String 类型)* @param key 键* @param value 值* @param expireTime 过期时间(秒,0 表示永久有效)*/void setString(String key, String value, long expireTime);/*** 获取数据(String 类型)* @param key 键* @return 值(若不存在则返回 null)*/String getString(String key);/*** 存储对象(自动序列化为 JSON)* @param key 键* @param value 对象(如 User、Order 等)* @param expireTime 过期时间(秒)* @param <T> 对象类型*/<T> void setObject(String key, T value, long expireTime);/*** 获取对象(自动反序列化为指定类型)* @param key 键* @param clazz 对象类型* @param <T> 对象类型* @return 对象(若不存在则返回 null)*/<T> T getObject(String key, Class<T> clazz);/*** 删除数据* @param key 键* @return 是否删除成功(true:删除成功;false:键不存在)*/boolean delete(String key);}4.1.2 RedisServiceImpl 实现类
package com.example.redisdemo.service.impl;import com.example.redisdemo.service.RedisService;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.concurrent.TimeUnit;@Servicepublic class RedisServiceImpl implements RedisService {// 注入自定义的 RedisTemplate@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Overridepublic void setString(String key, String value, long expireTime) {// 使用 opsForValue() 操作 String 类型数据redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);}@Overridepublic String getString(String key) {Object value = redisTemplate.opsForValue().get(key);return value != null ? value.toString() : null;}@Overridepublic <T> void setObject(String key, T value, long expireTime) {// 自动将对象序列化为 JSON 存储redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);}@Overridepublic <T> T getObject(String key, Class<T> clazz) {// 自动将 JSON 反序列化为指定类型对象Object value = redisTemplate.opsForValue().get(key);return value != null ? (T) value : null;}@Overridepublic boolean delete(String key) {return redisTemplate.delete(key);}}redisTemplate.opsForValue():操作 String 类型数据(最常用);
redisTemplate.opsForHash():操作 Hash 类型数据(适合存储对象的多个字段);
redisTemplate.opsForList():操作 List 类型数据(适合实现队列、栈等);
set(...) 方法的 TimeUnit.SECONDS 表示过期时间单位为 “秒”,还支持 MINUTES(分钟)、HOURS(小时)等。
4.2 编写测试接口(Controller)
package com.example.redisdemo.controller;import com.example.redisdemo.service.RedisService;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController@RequestMapping("/redis")public class RedisController {@Resourceprivate RedisService redisService;// 测试存储 String 类型@PostMapping("/string")public String setString(@RequestParam String key,@RequestParam String value,@RequestParam(defaultValue = "3600") long expireTime) {redisService.setString(key, value, expireTime);return "String 数据存储成功!key=" + key + ", value=" + value;}// 测试获取 String 类型@GetMapping("/string/{key}")public String getString(@PathVariable String key) {String value = redisService.getString(key);return "获取 String 数据:key=" + key + ", value=" + (value != null ? value : "null");}// 测试存储对象(以 User 为例)@PostMapping("/object")public String setObject(@RequestParam String key,@RequestParam String username,@RequestParam Integer age,@RequestParam(defaultValue = "3600") long expireTime) {// 创建 User 对象(实际项目中建议单独定义 User 实体类)User user = new User(username, age);redisService.setObject(key, user, expireTime);return "对象存储成功!key=" + key + ", user=" + user;}// 测试获取对象@GetMapping("/object/{key}")public User getObject(@PathVariable String key) {return redisService.getObject(key, User.class);}// 测试删除数据@DeleteMapping("/{key}")public String delete(@PathVariable String key) {boolean success = redisService.delete(key);return success ? "删除成功!key=" + key : "删除失败!key=" + key + " 不存在";}// 内部静态类:模拟 User 实体(实际项目中建议单独创建实体类)static class User {private String username;private Integer age;public User() {} // 必须有默认构造函数,否则 JSON 反序列化会失败public User(String username, Integer age) {this.username = username;this.age = age;}// Getter 和 Setter(必须,否则 JSON 序列化/反序列化无法获取/设置属性)public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public Integer getAge() { return age; }public void setAge(Integer age) { this.age = age; }@Overridepublic String toString() {return "User{username='" + username + "', age=" + age + "}";}}}五、测试 Redis 功能
5.1 启动 Spring Boot 项目
5.2 接口测试(Postman 或浏览器)
5.2.1 测试存储 String 类型数据
请求方式:POST
参数说明:
key=testString:自定义键名
value=HelloRedis:存储的字符串值
expireTime=3600:过期时间 1 小时(默认值,可省略)
预期响应:String 数据存储成功!key=testString, value=HelloRedis
5.2.2 测试获取 String 类型数据
请求方式:GET
预期响应:获取 String 数据:key=testString, value=HelloRedis
5.2.3 测试存储 Object 类型数据
请求方式:POST
参数说明:
key=testUser:键名
username=ZhangSan、age=25:User 对象的属性
预期响应:对象存储成功!key=testUser, user=User{username='ZhangSan', age=25}
5.2.4 测试获取 Object 类型数据
请求方式:GET
预期响应:JSON 格式的 User 对象
{"username": "ZhangSan","age": 25}5.2.5 测试删除数据
请求方式:DELETE
预期响应:删除成功!key=testString
验证:再次调用 “获取 String 数据” 接口,响应应为 获取 String 数据:key=testString, value=null
5.3 通过 Redis 客户端验证数据(可选)
打开 CMD 窗口,进入 Redis 解压目录,执行 redis-cli.exe -h 127.0.0.1 -p 6379 连接 Redis;
若 Redis 配置了密码,需先执行 auth 123456(替换为你的密码)进行认证;
执行以下命令查看数据:
# 查看所有键(验证键是否存在)keys *# 获取 String 类型数据(若未删除 testString)get testString# 获取 Object 类型数据(testUser 存储的是 JSON 字符串)get testUser
预期结果:
get testString 返回 HelloRedis(未删除时);
get testUser 返回 {"username":"ZhangSan","age":25},证明 JSON 序列化生效,无乱码。
六、常见问题与解决方案
6.1 连接 Redis 失败(Could not connect to Redis server)
可能原因:
Redis 服务器未启动;
Redis 配置的 host 或 port 错误;
远程 Redis 服务器未开放 6379 端口;
Redis 配置了密码,但项目中未配置 spring.redis.password(或密码错误)。
解决方案:
本地 Redis:执行 redis-server.exe redis.windows.conf 启动服务;
检查 application.yml 中 spring.redis.host 和 spring.port 是否与 Redis 服务器一致;
远程 Redis(如阿里云):
在服务器安全组中开放 6379 端口;
确认 spring.redis.password 与 Redis 服务器密码一致,若未设置密码则删除该配置。
6.2 数据反序列化失败(Could not read JSON document)
可能原因:
实体类(如 User)缺少 默认无参构造函数;
实体类的属性缺少 Getter/Setter 方法;
自定义 RedisTemplate 时,Value 序列化方式配置错误。
解决方案:
为实体类添加默认无参构造函数(即使手动写了有参构造,也需显式定义无参构造);
确保实体类的所有属性都有 Getter/Setter 方法(JSON 序列化需通过反射获取 / 设置属性值);
检查 RedisConfig 中 Value 序列化配置,确保使用 GenericJackson2JsonRedisSerializer:
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
6.3 Redis 客户端查看数据乱码
可能原因:
解决方案:
七、总结与进阶方向
7.1 本文核心要点回顾
环境准备:确保 JDK、Spring Boot、Redis 版本兼容,本地 Redis 启动后通过 ping 验证;
依赖配置:引入 spring-boot-starter-data-redis 和 commons-pool2(连接池),简化客户端集成;
核心配置:通过 application.yml 配置 Redis 服务器信息和连接池参数,自定义 RedisTemplate 解决序列化问题;
功能实现:通过 RedisTemplate 封装 String 和 Object 类型的增删改查,结合 Controller 接口测试;
问题排查:针对连接失败、序列化异常、数据乱码等常见问题,掌握关键解决思路。
7.2 进阶学习方向
Redis 数据结构深化:学习 Hash(存储对象字段)、List(实现消息队列)、Set(去重)、ZSet(排序)的用法,通过 redisTemplate.opsForHash()、opsForList() 等 API 实现;
缓存策略优化:
配置缓存过期时间避免数据过期;
实现缓存穿透(空值缓存)、缓存击穿(互斥锁)、缓存雪崩(过期时间加随机值)的解决方案;
分布式锁:基于 Redis 实现分布式锁(如 setIfAbsent 方法),解决多服务并发问题;
Redis 集群:学习 Redis 主从复制、哨兵模式、Cluster 集群配置,应对高可用和高并发场景;
Spring Cache 整合:使用 @Cacheable、@CachePut、@CacheEvict 注解简化缓存操作,减少重复代码。
