SpringBoot18-集成Redis
一、SpringBoot集成Redis1-1、先理解什么是 RedisRedis 就是一个超快的数据库但它专门存数据在内存里不是硬盘。你可以把它想象成一个超级快的“笔记本”用来暂时记一些数据。比如登录状态、验证码、排行榜、购物车、点赞数……为什么用 Redis因为它速度非常快比 MySQL 快几十~上百倍可以自动过期适合存验证码、token可以解决并发问题比如抢票、库存扣减1-2、第一步安装 Redis1如果你用Windows下载 Redis for Windows无需安装https://github.com/tporadowski/redis/releases打开redis-server.exe就启动了。2如果是Macbrew install redis brew services start redis启动成功后Redis 会在6379端口上运行。3验证是否安装了redis1-3、第二步在 Spring Boot 项目中加依赖在pom.xml加dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency就这样Redis 支持就进项目了。1-4、第三步配置连接 Redis在application.yml里写spring: data: redis: host: 127.0.0.1 # 本机 port: 6379 # 默认端口如果你 Redis 设置了密码这里再加password: xxx1-5、第四步写一个最简单的 Redis 代码存 取1、写一个 Service 类Service public class RedisTestService { Autowired private StringRedisTemplate stringRedisTemplate; // 专门操作字符串 // 存数据 public void saveData() { stringRedisTemplate.opsForValue().set(name, Tom); } // 取数据 public String getData() { return stringRedisTemplate.opsForValue().get(name); } }Maven中添加了redis的依赖之后StringRedisTemplate就能直接注入使用了2、写个 Controller 调用它RestController public class TestController { Autowired private RedisTestService redisTestService; GetMapping(/save) public String save() { redisTestService.saveData(); return 保存成功; } GetMapping(/get) public String get() { return redisTestService.getData(); } }3、运行测试浏览器访问① 保存数据http://localhost:8080/save② 获取数据http://localhost:8080/get你将看到返回Tom你已经成功用 Spring Boot 操作 Redis 了4、或者直接写一个redis的测试类1-6、小结二、令牌主动失效目标登录成功 → 把发给浏览器的令牌token同时存进 Redis每次请求在拦截器里比对“浏览器带来的令牌 Redis里为该用户保存的令牌”用户改密成功 → 主动删除 Redis 里的旧令牌使其立刻失效。2-1、Redis 存储设计双向映射便于比对和失效auth:user:{userId} - {token}用户当前有效 token便于改密时一把踢下线auth:token:{token} - {userId}用 token 找到用户拦截器校验时用两个 key 都设置相同TTL比如 2 小时再次登录会覆盖旧 token。2-2、登录生成并落库含顶替旧令牌Service RequiredArgsConstructor public class AuthService { private final StringRedisTemplate redis; // 令牌有效期 private static final long TOKEN_TTL_MINUTES 120; public String login(Long userId, String rawPassword) { // 1. 这里省略账号密码校验查库比对哈希 // if (!passOK) throw new BizException(...); // 2. 生成新 token String token UUID.randomUUID().toString(); // 3. 顶替旧 token如果有就删 String oldToken redis.opsForValue().get(auth:user: userId); if (oldToken ! null) { redis.delete(auth:token: oldToken); } // 4. 双向写入 过期时间 redis.opsForValue().set(auth:user: userId, token, TOKEN_TTL_MINUTES, TimeUnit.MINUTES); redis.opsForValue().set(auth:token: token, String.valueOf(userId), TOKEN_TTL_MINUTES, TimeUnit.MINUTES); // 5. 返回给前端 return token; } // 退出登录前端丢弃 服务端删除 public void logout(String token) { if (token null) return; String userId redis.opsForValue().get(auth:token: token); if (userId ! null) { redis.delete(auth:token: token); redis.delete(auth:user: userId); } } // 改密后让旧令牌立即失效主动删除 public void invalidateUserTokenOnPasswordChange(Long userId) { String oldToken redis.opsForValue().get(auth:user: userId); if (oldToken ! null) { redis.delete(auth:user: userId); redis.delete(auth:token: oldToken); } } }示例 Controller返回 token 给前端退出改密后失效RestController RequiredArgsConstructor public class AuthController { private final AuthService authService; PostMapping(/login) public String login(RequestParam Long userId, RequestParam String password) { return authService.login(userId, password); } PostMapping(/logout) public void logout(RequestHeader(Authorization) String token) { authService.logout(token); } // 改密成功后调用旧 token 立刻失效 PostMapping(/password/change) public String changePwd(RequestParam Long userId, RequestParam String oldPwd, RequestParam String newPwd) { // 1) 校验旧密码并更新为新密码略 // 2) 主动失效旧令牌 authService.invalidateUserTokenOnPasswordChange(userId); // 3) 可选直接让用户重新登录或这里返回新 token return OK; } }2-3、拦截器校验比对“请求令牌 Redis 存的令牌”Component RequiredArgsConstructor public class LoginInterceptor implements HandlerInterceptor { private final StringRedisTemplate redis; Override public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception { String token req.getHeader(Authorization); if (token null || token.isEmpty()) { resp.setStatus(401); return false; } // 1) 通过 token 找 userId无则说明 token 无效或过期 String userId redis.opsForValue().get(auth:token: token); if (userId null) { resp.setStatus(401); return false; } // 2) 再用 userId 取当前有效 token必须“完全相等”才算有效 String currentToken redis.opsForValue().get(auth:user: userId); if (!token.equals(currentToken)) { // 出现这种情况用户在别处重新登录/改了密码/已被踢下线 resp.setStatus(401); return false; } // 校验通过 return true; } }注册拦截器Configuration RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { private final LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/**) .excludePathPatterns(/login); // 登录接口放行 } }2-4、前端怎么带令牌登录后保存服务端返回的token之后每个请求都在请求头带上Authorization: token名字可自定义统一即可2-5、可选增强自动续期活跃会话不掉线在拦截器校验通过后给两个 key 续命重置 TTL// 校验通过后 redis.expire(auth:token: token, 120, TimeUnit.MINUTES); redis.expire(auth:user: userId, 120, TimeUnit.MINUTES);单设备登录上面的“顶替旧令牌”已经实现了单设备登录——新登录会让旧 token 失效。多端共存把auth:user:{userId}改成 Set允许保存多个 tokenPC/手机各一个改密时删除该用户所有 token。

相关新闻

《手把手教你写一个生产级 K8s Operator:CRD + Controller + Webhook 全链路实践》

《手把手教你写一个生产级 K8s Operator:CRD + Controller + Webhook 全链路实践》

K8s Operator 控制器 进行深度全链路实践,增加以下生产级特性:并发协调控制(MaxConcurrentReconciles)事件记录(Event Recorder)最终一致性保证(Requeue 策略优化)子资源冲突处理&am…

2026/10/17 20:39:28 阅读更多 →
软路由玩家必看:在PVE7.3上实现iKuai+OpenWRT双路由+NAS+Win10的5个性能优化技巧

软路由玩家必看:在PVE7.3上实现iKuai+OpenWRT双路由+NAS+Win10的5个性能优化技巧

软路由性能调优实战:从J4125到PVE,榨干每一分硬件潜力的进阶指南 如果你已经成功在J4125小主机上部署了PVE,并搭建了iKuai主路由、OpenWRT旁路由、NAS乃至Windows 10的All-in-One系统,那么恭喜你,已经迈入了高阶玩家的行列。但搭建成功只是第一步,真正的挑战在于如何让这…

2026/10/18 9:24:50 阅读更多 →
厨卫翻新不搬家如何选择:牛牛快装等服务适用场景

厨卫翻新不搬家如何选择:牛牛快装等服务适用场景

厨卫翻新不搬家:如何理性选择“快与净”的局部改造服务在老旧小区的居住体验中,厨卫空间往往是痛点最集中的区域。水管老化、瓷砖空鼓、防水失效等问题直接影响日常生活品质。然而,传统装修伴随的噪音污染、粉尘飞扬以及漫长的工期&#xff0…

2026/10/18 9:25:18 阅读更多 →

最新新闻

开源代码评审工具open-code-review:把Code Review变成工程化流程

开源代码评审工具open-code-review:把Code Review变成工程化流程

现在很多团队谈到 Code Review,第一反应就是"又慢又烦",评审人打开 PR 看一眼就 Approve,或者干脆在群里吼一句"谁有空帮我看看",然后一整天没人理。我做了几年研发管理和架构工作,见过太多 Revie…

2026/10/19 19:51:14 阅读更多 →
小说阅读平台章节模块设计:从ThinkPHP到Laravel重构实战

小说阅读平台章节模块设计:从ThinkPHP到Laravel重构实战

做小说在线阅读平台这件事,我最深的体会是:真正决定项目上限的往往不是花里胡哨的功能,而是最基础的那套章节模块。标题里的“章节设计”四个字,看起来只是建一张表、写几个接口,实际做下来才发现,它把正文…

2026/10/19 19:50:13 阅读更多 →
毕业论文开题报告AI优化指南:9款工具组合与提示词实践

毕业论文开题报告AI优化指南:9款工具组合与提示词实践

毕业季又到了,朋友圈里一片哀嚎。我发现大家用AI工具写开题报告,基本就两种用法:要么直接复制粘贴标题让AI代写全文,要么把AI当成搜索引擎问几个问题。结果交上去的初稿被导师批得体无完肤,要么内容空泛不知所云&#…

2026/10/19 19:50:13 阅读更多 →
Caveman提示词压缩法:大模型API输出Token成本直降80%

Caveman提示词压缩法:大模型API输出Token成本直降80%

前阵子被大模型API账单吓到了,一个批量打标任务跑下来,几千块钱说没就没。细看消耗明细,真正的开销大头不在输入,反而在输出这一侧——模型每次回答都带着一大段解释、铺垫、客套话,一句话能说清的事硬要写一百个Token…

2026/10/19 19:50:13 阅读更多 →
Windows客户端与Linux服务端跨平台联调:从环境差异到根因定位

Windows客户端与Linux服务端跨平台联调:从环境差异到根因定位

上周五下午快下班的时候,运维转过来一个问题:某桌面客户端连不上刚上线的 Linux 服务端,界面一直转圈,过几分钟才弹一个超时提示。我跨过半个工区去看,发现客户端同事已经在重新编译代码,准备打印一堆调试信…

2026/10/19 19:50:13 阅读更多 →
PADS、AD、Cadence 互转实战:四条链路版本配置与避坑指南

PADS、AD、Cadence 互转实战:四条链路版本配置与避坑指南

简介:这份文档面向使用PADS、Altium Designer与Cadence的电子工程师及PCB设计学习者,聚焦不同EDA工具之间设计文件互操作的痛点,系统梳理了PADS转AD、AD转Cadence、AD转PADS、Cadence转PADS等常见转换路径。内容覆盖原理图与PCB两条主线&…

2026/10/19 19:50:13 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →