news 2026/4/12 9:51:50

《Spring Boot 集成 Redis 完整教程:从配置到缓存实战(附源码)》

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《Spring Boot 集成 Redis 完整教程:从配置到缓存实战(附源码)》

一、前言

在分布式系统开发中,缓存是提升接口响应速度、减轻数据库压力的关键手段。Redis 作为高性能的键值对数据库,凭借其支持多种数据结构、读写速度快、可持久化等特性,成为 Spring Boot 项目的首选缓存方案。本文将从环境准备、依赖配置、代码实现、缓存策略优化四个维度,带大家从零实现 Spring Boot 与 Redis 的无缝集成,附完整代码示例和常见问题解决方案。

二、环境准备

1. 基础环境
  • JDK 1.8+
  • Spring Boot 2.7.x(兼容 2.x 版本,3.x 版本配置略有差异)
  • Redis 6.2.x(本地或云服务器部署均可)
  • Maven 3.6+
2. Redis 环境验证

确保 Redis 服务正常启动,可通过以下命令测试连接:

# 本地 Redis 连接

redis-cli -h 127.0.0.1 -p 6379

# 输入 ping,返回 PONG 则表示连接正常

127.0.0.1:6379> ping

PONG

三、核心配置步骤

1. 引入 Maven 依赖

在 pom.xml 中添加 Spring Boot 整合 Redis 的核心依赖,无需额外引入 Redis 客户端(Spring Boot 自动适配 Lettuce 客户端):

Redis starter -->

<dependency>

>org.springframework.boot

-boot-starter-data-redis</artifactId>

>

依赖(Lettuce 底层依赖 commons-pool2) -->

>

.apache.commons ool2</dependency>

2. 配置 application.yml

在配置文件中添加 Redis 连接信息、连接池配置和缓存通用配置:

spring:

# Redis 配置

redis:

host: 127.0.0.1 # Redis 服务器地址

port: 6379 # 端口号

password: "" # 若未设置密码则留空

database: 0 # 操作的数据库索引(默认 0)

# Lettuce 连接池配置

lettuce:

pool:

max-active: 8 # 最大连接数

max-idle: 8 # 最大空闲连接数

min-idle: 2 # 最小空闲连接数

max-wait: -1ms # 最大等待时间(-1 表示无限制)

# 缓存通用配置

cache:

type: redis # 缓存类型为 Redis

redis:

time-to-live: 3600000ms # 缓存默认过期时间(1 小时)

cache-null-values: false # 是否缓存 null 值(避免缓存穿透)

use-key-prefix: true # 是否使用缓存前缀(默认前缀为 cache:)

3. 自定义 Redis 配置类

Spring Boot 自动配置的 RedisTemplate 序列化方式为 JDK 序列化,存在可读性差、占用空间大的问题。我们通过自定义配置类,将序列化方式改为 JSON 格式:

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.cache.RedisCacheConfiguration;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

import org.springframework.data.redis.serializer.RedisSerializationContext;

import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration

@EnableCaching // 开启缓存注解支持

public class RedisConfig {

/**

* 自定义 RedisTemplate:解决默认序列化问题

*/

@Bean

public RedisTemplate, Object> redisTemplate(RedisConnectionFactory factory) {

RedisTemplate, Object> template = new RedisTemplate template.setConnectionFactory(factory);

// 字符串序列化器(key 采用 String 序列化)

StringRedisSerializer stringSerializer = new StringRedisSerializer();

template.setKeySerializer(stringSerializer);

template.setHashKeySerializer(stringSerializer);

// JSON 序列化器(value 采用 JSON 序列化)

GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();

template.setValueSerializer(jsonSerializer);

template.setHashValueSerializer(jsonSerializer);

// 初始化模板

template.afterPropertiesSet();

return template;

}

/**

* 自定义 RedisCacheManager:统一缓存配置

*/

@Bean

public RedisCacheManager cacheManager(RedisConnectionFactory factory) {

// 缓存配置:JSON 序列化 + 过期时间

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()

.entryTtl(Duration.hours(1)) // 默认过期时间 1 小时

.serializeKeysWith(RedisSerializationContext.SerializationPair

.fromSerializer(new StringRedisSerializer())) // key 序列化

.serializeValuesWith(RedisSerializationContext.SerializationPair

.fromSerializer(new GenericJackson2JsonRedisSerializer())) // value 序列化

.disableCachingNullValues(); // 不缓存 null 值

// 构建缓存管理器

return RedisCacheManager.builder(factory)

.cacheDefaults(config)

.build();

}

}

四、实战:缓存注解的使用

1. 实体类准备

创建用户实体类(需实现序列化接口,或使用 JSON 序列化时无需显式实现):

import lombok.Data;

@Data

public class User {

private Long id;

private String username;

private String phone;

private Integer age;

}

2. Service 层缓存实现

通过 @Cacheable、@CachePut、@CacheEvict 三个核心注解实现缓存的增删改查:

import org.springframework.cache.annotation.CacheEvict;

import org.springframework.cache.annotation.CachePut;

import org.springframework.cache.annotation.Cacheable;

import org.springframework.stereotype.Service;

import java.util.HashMap;

import java.util.Map;

@Service

public class UserService {

// 模拟数据库存储

private static final Map> USER_DB = new HashMap<>();

static {

// 初始化测试数据

USER_DB.put(1L, new User(1L, "张三", "13800138000", 25));

USER_DB.put(2L, new User(2L, "李四", "13900139000", 30));

}

/**

* 查询用户:缓存存在则返回缓存数据,不存在则执行方法并缓存结果

* key:缓存键(默认使用方法参数作为 key,这里显式指定为 user::id)

*/

@Cacheable(value = "user", key = "#id", unless = "#result == null")

public User getUserById(Long id) {

System.out.println("===== 执行数据库查询,id:" + id + " =====");

return USER_DB.get(id);

}

/**

* 更新用户:执行方法后,更新缓存(覆盖原缓存)

*/

@CachePut(value = "user", key = "#user.id")

public User updateUser(User user) {

System.out.println("===== 执行数据库更新,id:" + user.getId() + " =====");

USER_DB.put(user.getId(), user);

return user;

}

/**

* 删除用户:执行方法后,删除对应缓存

*/

@CacheEvict(value = "user", key = "#id")

public void deleteUser(Long id) {

System.out.println("===== 执行数据库删除,id:" + id + " =====");

USER_DB.remove(id);

}

}

3. 测试接口(Controller 层)

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

@RestController

@RequestMapping("/user")

public class UserController {

@Autowired

private UserService userService;

@GetMapping("/{id}")

public User getUser(@PathVariable Long id) {

return userService.getUserById(id);

}

@PutMapping

public User updateUser(@RequestBody User user) {

return userService.updateUser(user);

}

@DeleteMapping("/{id}")

public String deleteUser(@PathVariable Long id) {

userService.deleteUser(id);

return "删除成功";

}

}

五、缓存优化与避坑指南

1. 缓存穿透问题解决
  • 原因:查询不存在的 key 时,缓存未命中,导致频繁访问数据库。
  • 解决方案:
    1. 配置 cache-null-values: true(缓存 null 值,过期时间设为 5-10 分钟);
    1. 接口层增加参数校验,过滤无效 id(如小于 1 的 id)。
2. 缓存击穿问题解决
  • 原因:热点 key 过期瞬间,大量请求同时访问数据库。
  • 解决方案:
    1. 热点 key 设置永不过期(或超长过期时间);
    1. 使用互斥锁(如 Redis 的 SETNX),确保同一时间只有一个请求更新缓存。
3. 缓存雪崩问题解决
  • 原因:大量缓存 key 同时过期,导致数据库压力骤增。
  • 解决方案:
    1. 缓存过期时间添加随机值(如 time-to-live: ${random.int[3600000, 7200000]}ms);
    1. 核心业务缓存集群部署,避免单点故障。
4. 序列化问题注意事项
  • 避免使用 JDK 序列化:可读性差、占用空间大,优先使用 JSON 序列化;
  • 实体类若使用 Lombok,需确保有无参构造函数(JSON 反序列化依赖);
  • 若实体类属性有新增 / 删除,建议清理旧缓存,避免反序列化失败。

六、总结

本文详细介绍了 Spring Boot 集成 Redis 的完整流程,从环境搭建、配置优化到实战应用,覆盖了缓存注解的核心使用场景和常见问题解决方案。通过 Redis 缓存,可显著提升接口响应速度(毫秒级响应),尤其适用于高频查询、数据变更较少的场景(如用户信息、商品详情等)。

后续可进一步探索 Redis 的高级特性,如分布式锁、消息队列、地理位置存储等,欢迎在评论区交流探讨!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/27 17:59:49

5分钟修复Dokploy中.traefik.me证书错误,恢复安全访问

Dokploy作为开源的Vercel、Netlify和Heroku替代方案&#xff0c;提供了便捷的容器化部署体验。然而很多用户在使用过程中会遇到.traefik.me域名的SSL证书失效问题&#xff0c;导致浏览器显示"您的连接不是私密连接"警告。本文将为你提供完整的诊断和修复方案&#xf…

作者头像 李华
网站建设 2026/4/12 3:11:21

从微信到阿里,豆包手机为何成了互联网巨头的“眼中钉”?

2025年12月&#xff0c;豆包手机的横空出世犹如一颗重磅炸弹&#xff0c;瞬间震动了整个 智能手机行业。这款搭载 AI助手系统 的手机不仅突破了传统的 操作系统 框架&#xff0c;更为用户带来了前所未有的智能体验。然而&#xff0c;令人意外的是&#xff0c;豆包手机的成功却并…

作者头像 李华
网站建设 2026/4/11 7:47:48

Dify代码执行终极指南:从权限诊断到可视化图表的完整解决方案

Dify代码执行终极指南&#xff1a;从权限诊断到可视化图表的完整解决方案 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程&#xff0c;自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/aw/Awesom…

作者头像 李华
网站建设 2026/4/8 9:38:06

21、网络服务器相关知识详解

网络服务器相关知识详解 在网络环境中,服务器的管理和维护涉及多个方面,包括FTP服务、邮件服务以及域名服务等。下面将详细介绍这些服务的相关内容。 1. FTP服务管理 在使用FTP服务时,有两个重要的方面需要关注:数据传输和磁盘空间。 - 数据传输 :所有的FTP下载都会…

作者头像 李华
网站建设 2026/4/12 2:56:01

2025年最新企业即时通讯(IM)软件推荐排名(附产品详解)

在数字化转型浪潮中&#xff0c;企业即时通讯软件&#xff08;EIM&#xff09;已从单一沟通工具进化为连接组织、提升协作效率的核心载体。2025年的市场呈现出“安全为基、场景为王、智能赋能”的显著特征&#xff0c;其中易秒办&#xff08;e-Mobile&#xff09;凭借其“五大统…

作者头像 李华