Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战
🚀 作者主页: 有来技术
🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot
🌺 仓库主页: Gitee 💫 Github 💫 GitCode
💖 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请纠正!
目录
- 什么是 Spring Cache?
- Spring Cache 常用 API
- @Cacheable
- @CacheEvict
- @CachePut
- @Caching
- Spring Boot 整合 Spring Cache (Redis 缓存)
- 项目依赖 pom.xml
- 项目配置 application.yml
- 自动装配配置类 RedisCacheConfig
- Spring Boot 路由缓存实战
- 获取路由数据缓存
- 更新路由缓存失效
- Spring Cache 问题整理
- @Cacheable 缓存的 key 双冒号
- 结语
- 开源项目
什么是 Spring Cache?
Spring Cache是Spring框架提供的一层缓存抽象,旨在简化应用程序中的缓存管理。通过使用Spring Cache,开发者能够在方法级别方便地定义缓存策略,提高应用性能、响应速度,并减轻底层数据源的负载。该框架提供一系列注解,如@Cacheable
、@CacheEvict
、@CachePut
,以及对多种底层缓存实现的支持,如EhCache、Redis等。它为应用程序提供了一种统一、方便、灵活的缓存管理方式,允许开发者通过简单的配置实现复杂的缓存逻辑,同时与Spring框架紧密集成。这种抽象层的存在使得在更改底层缓存框架时更为轻松,同时提供了一致的配置接口和更强大的高级特性。
Spring Cache 常用 API
@Cacheable
@Cacheable
: 用于标记一个方法的结果应该被缓存。当在该方法被调用时,Spring首先检查缓存中是否已经有了预期的结果,如果有,直接返回缓存中的结果而不执行实际的方法体。
javaCopy code@Cacheable(cacheNames = "exampleCache", key = "'exampleKey'")
public String getCachedData() {// 执行实际的方法体,结果会被缓存
}
@CacheEvict
@CacheEvict
: 用于标记一个方法在执行后清空缓存。可以指定清空的缓存名称和清空的条件。
javaCopy code@CacheEvict(cacheNames = "exampleCache", key = "'exampleKey'")
public void clearCache() {// 执行实际的方法体,之后清空缓存
}
@CachePut
@CachePut
: 用于标记一个方法的结果应该被放入缓存,常用于在方法执行后更新缓存。
javaCopy code@CachePut(cacheNames = "exampleCache", key = "'exampleKey'")
public String updateCache() {// 执行实际的方法体,结果会被放入缓存
}
@Caching
@Caching
: 允许同时应用多个缓存操作注解。
javaCopy code@Caching(evict = {@CacheEvict(cacheNames = "cache1", key = "'key1'"),@CacheEvict(cacheNames = "cache2", key = "'key2'")}
)
public void clearMultipleCaches() {// 执行实际的方法体,清空多个缓存
}
Spring Boot 整合 Spring Cache (Redis 缓存)
完整项目源码:youlai-boot
项目依赖 pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
项目配置 application.yml
spring:data:redis:database: 6host: localhostport: 6379password: 123456timeout: 10slettuce:pool:# 连接池最大连接数 默认8 ,负数表示没有限制max-active: 8# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认-1max-wait: -1# 连接池中的最大空闲连接 默认8max-idle: 8# 连接池中的最小空闲连接 默认0min-idle: 0cache:# 缓存类型 redis、none(不使用缓存)type: redis# 缓存时间(单位:ms)redis:time-to-live: 3600000# 缓存null值,防止缓存穿透cache-null-values: true
自动装配配置类 RedisCacheConfig
package com.youlai.system.config;import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;/*** Redis 缓存配置** @author haoxr* @since 2023/12/4*/
@EnableCaching
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
public class RedisCacheConfig {/*** 自定义 RedisCacheManager* <p>* 修改 Redis 序列化方式,默认 JdkSerializationRedisSerializer** @param redisConnectionFactory {@link RedisConnectionFactory}* @param cacheProperties {@link CacheProperties}* @return {@link RedisCacheManager}*/@Beanpublic RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory, CacheProperties cacheProperties){return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)).cacheDefaults(redisCacheConfiguration(cacheProperties)).build();}/*** 自定义 RedisCacheConfiguration** @param cacheProperties {@link CacheProperties}* @return {@link RedisCacheConfiguration}*/@BeanRedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()));config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));CacheProperties.Redis redisProperties = cacheProperties.getRedis();if (redisProperties.getTimeToLive() != null) {config = config.entryTtl(redisProperties.getTimeToLive());}if (!redisProperties.isCacheNullValues()) {config = config.disableCachingNullValues();}if (!redisProperties.isUseKeyPrefix()) {config = config.disableKeyPrefix();}config = config.computePrefixWith(name -> name + ":");// 覆盖默认key双冒号 CacheKeyPrefix#prefixedreturn config;}}
Spring Boot 路由缓存实战
完整项目源码:youlai-boot
获取路由数据缓存
获取路由列表,通过 @Cacheable
注解,将方法返回的路由列表数据缓存至 Redis。当再次请求时,不再进入方法体,而是直接从 Redis 中读取缓存数据并返回,以提高性能。
/*** 获取路由列表*/@Override@Cacheable(cacheNames = "menu", key = "'routes'") // cacheNames 为必填项,key 需要使用引号,否则会被识别为变量。public List<RouteVO> listRoutes() {List<RouteBO> menuList = this.baseMapper.listRoutes();return buildRoutes(SystemConstants.ROOT_NODE_ID, menuList);}
更新路由缓存失效
若需要在路由信息更新时使缓存失效,可以使用 @CacheEvict
注解,它用于在方法执行之后(默认)从缓存中移除条目。
/*** 新增/修改菜单*/@Override@CacheEvict(cacheNames = "menu", key = "'routes'",beforeInvocation = true)public boolean saveMenu(MenuForm menuForm) {String path = menuForm.getPath();MenuTypeEnum menuType = menuForm.getType();// 如果是目录if (menuType == MenuTypeEnum.CATALOG) {if (menuForm.getParentId() == 0 && !path.startsWith("/")) {menuForm.setPath("/" + path); // 一级目录需以 / 开头}menuForm.setComponent("Layout");}// 如果是外链else if (menuType == MenuTypeEnum.EXTLINK) {menuForm.setComponent(null);}SysMenu entity = menuConverter.form2Entity(menuForm);String treePath = generateMenuTreePath(menuForm.getParentId());entity.setTreePath(treePath);return this.saveOrUpdate(entity);}
更新菜单后,Redis 中缓存的路由数据将被清除。再次获取路由时,才会将新的路由数据缓存到 Redis 中。
Spring Cache 问题整理
@Cacheable 缓存的 key 双冒号
默认情况下 @Cacheable 使用双冒号 ::
拼接 cacheNames
和 key
@Cacheable(cacheNames = "menu", key = "'routes'")
参考源码 RedisCacheConfiguration#prefixCacheNameWith
如果需要将双冒号改成单个冒号,需要重写 RedisCacheConfiguration#computePrefixWith
方法
config = config.computePrefixWith(name -> name + ":");//覆盖默认key双冒号 CacheKeyPrefix#prefixed
结语
Spring Cache 为 Spring 应用程序提供了简便的缓存管理抽象,通过注解如 @Cacheable
、@CacheEvict
、@CachePut
,开发者能方便定义缓存策略。整合Spring Boot 与 Redis
缓存实例展示了如何配置、使用Spring Cache,提升应用性能。通过实战演示菜单路由缓存,突显 @Cacheable
和 @CacheEvict
的实际应用,以及解决 @Cacheable
默认key双冒号的问题。
开源项目
- SpringCloud + Vue3 微服务商城
Github | Gitee | |
---|---|---|
后端 | youlai-mall 🍃 | youlai-mall 🍃 |
前端 | mall-admin🌺 | mall-admin 🌺 |
移动端 | mall-app 🍌 | mall-app 🍌 |
- SpringBoot 3+ Vue3 单体权限管理系统
Github | Gitee | |
---|---|---|
后端 | youlai-boot 🍃 | youlai-boot 🍃 |
前端 | vue3-element-admin 🌺 | vue3-element-admin 🌺 |
相关文章:

Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…...

kubeadm 安装k8s1.28.x 底层走containerd 容器
1. k8s1.28.x 的概述 1.1 k8s 1.28.x 更新 Kubernetes v1.28 是 2023 年的第二个大版本更新,包含了 46 项主要的更新。 而今年发布的第一个版本 v1.27 有近 60 项,所以可以看出来,在发布节奏调整后, 每个 Kubernetes 版本中都会包…...

“分割“安卓用户,对标iOS,鸿蒙崛起~
近期关于**“华为于明年推出不兼容安卓的鸿蒙版本”**的消息传出,引起了业界的热议关注。自从2019年8月,美国制裁下,华为不再能够获得谷歌安卓操作系统相关付费服务,如此情况下,华为“备胎”鸿蒙操作系统一夜转正。 华…...

【Vulnhub 靶场】【hacksudo: ProximaCentauri】【简单 - 中等】【20210608】
1、环境介绍 靶场介绍:https://www.vulnhub.com/entry/hacksudo-proximacentauri,709/ 靶场下载:https://download.vulnhub.com/hacksudo/hacksudo-ProximaCentauri.zip 靶场难度:简单 - 中等 发布日期:2021年06月08日 文件大小&…...
share pool的组成
share pool的组成 3块区域:free,library cache,row cache 通过查看v$librarycache视图,可以监控library cache的活动情况,进一步衡量share pool设置是否合理; 其中reloads列,表示对象被重新加载的次数,在一个设置合…...

应用案例 | 基于三维视觉的汽车零件自动化拧紧解决方案
Part.1 引言 随着人们生活水平的提高,汽车作为理想的代步工具,逐渐成为人们生活中不可或缺的一部分。汽车的广泛应用,大大增加了汽车制造业的负荷。因此,如何提高生产效率和汽车性能,成为汽车制造业的首要关注话题。…...
Redis server启动源码
入口main函数 src/redis.c文件main函数 int main(int argc, char **argv) {struct timeval tv;/* We need to initialize our libraries, and the server configuration. */// 初始化库 #ifdef INIT_SETPROCTITLE_REPLACEMENTspt_init(argc, argv); #endif//设置本地时间setl…...
C++基础 强制转换
目录 static_cast:static_cast(expression) const_cast dynamic_cast reinterpret_cast C 提供以下几类转换 static_cast:static_cast<type-id>(expression) tatic_cast 主要用于以下几种情况: 用于显式地将一个表达式转换为另一…...

【python、opencv】opencv仿射变换原理及代码实现
opencv仿射变换原理 仿射变换是opencv的基本知识点,主要目的是将原始图片经过仿射变换矩阵,平移、缩放、旋转成目标图像。用数学公式表示就是坐标转换。 其中x,y是原始图像坐标,u,v是变换后的图像坐标。将公式转换为…...

mac本地部署stable-diffusion
下载Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" ①输入“1”选择中科大版本,然后输入Y(YES),直接输入开机密码(不显示)然后回车确认,开始下载 ②…...

dockers安装rabbitmq
RabbitMQ: easy to use, flexible messaging and streaming — RabbitMQhttps://www.rabbitmq.com/ Downloading and Installing RabbitMQ — RabbitMQ docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management 之后参照:dock…...

07、pytest指定要运行哪些用例
官方用例 # 目录结构 | |----test_mod.py | |----testing||----test_dir.py# content of test_mod.py import pytestdef func(x):return x 1def test_mod():print("test_mod function was invoked")assert func(3) 5def test_func():print("test_func was in…...
springboot集成cxf
<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://ma…...

快速认识什么是:Kubernetes
每次谈到容器的时候,除了Docker之外,都会说起 Kubernetes,那么什么是 Kubernetes呢?今天就来一起学快速入门一下 Kubernetes 吧!希望本文对您有所帮助。 Kubernetes,一种用于管理和自动化云中容器化工作负…...
YOLOv6 学习笔记
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、YOLOv6贡献和改进二、YOLOv6核心概念三、YOLOv6架构改进四、YOLOv6重参思想五、YOLOv6的损失函数总结 前言 在计算机视觉领域,目标检测技术一直…...

paypal贝宝怎么绑卡支付
一、PayPal是什么 PayPal是一个很多国家地区通用的支付渠道,我们可以把它理解为一项在线服务,相当于美国版的支付宝。你可以通过PayPal进行汇款和收款,相比传统的电汇和西联那类的汇款方式,PayPal更加简单和容易,被很…...

活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新
2023年11月28日,德州仪器(TI)嵌入式技术创新发展研讨会在上海顺利举办。作为TI中国第三方IDH,深圳市信驰达科技有限公司受邀参加,并设置展位,展出CC2340系列低功耗蓝牙模块及TPMS、蓝牙数字钥匙解决方案,与众多业内伙伴…...
Vue 循环走马灯
1、使用 transform: translateX(),循环将滚动内容在容器内偏移,超出容器部分隐藏; 2、避免滚动到末尾时出现空白,需要预留多几个。 3、一次循环偏移的距离scrollLoopWidth 可能受样式影响需要做些微调,比如单个item的…...

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux文件管理(3)》(27)
《Linux操作系统原理分析之Linux文件管理(3)》(27) 8 Linux文件管理8.6 文件管理和操作8.6.1 系统对文件的管理8.6.2 进程对文件的管理 8 Linux文件管理 8.6 文件管理和操作 8.6.1 系统对文件的管理 Linux 系统把所有打开的活动…...

【华为数据之道学习笔记】3-2 基础数据治理
基础数据用于对其他数据进行分类,在业界也称作参考数据。基础数据通常是静态的(如国家、币种),一般在业务事件发生之前就已经预先定义。它的可选值数量有限,可以用作业务或IT的开关和判断条件。当基础数据的取值发生变…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...