当前位置: 首页 > news >正文

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 使用双冒号 :: 拼接 cacheNameskey

@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 微服务商城
GithubGitee
后端youlai-mall 🍃youlai-mall 🍃
前端mall-admin🌺mall-admin 🌺
移动端mall-app 🍌mall-app 🍌
  • SpringBoot 3+ Vue3 单体权限管理系统
GithubGitee
后端youlai-boot 🍃youlai-boot 🍃
前端vue3-element-admin 🌺vue3-element-admin 🌺

相关文章:

Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…...

kubeadm 安装k8s1.28.x 底层走containerd 容器

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

“分割“安卓用户,对标iOS,鸿蒙崛起~

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

【Vulnhub 靶场】【hacksudo: ProximaCentauri】【简单 - 中等】【20210608】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/hacksudo-proximacentauri,709/ 靶场下载&#xff1a;https://download.vulnhub.com/hacksudo/hacksudo-ProximaCentauri.zip 靶场难度&#xff1a;简单 - 中等 发布日期&#xff1a;2021年06月08日 文件大小&…...

share pool的组成

share pool的组成 3块区域&#xff1a;free,library cache,row cache 通过查看v$librarycache视图&#xff0c;可以监控library cache的活动情况&#xff0c;进一步衡量share pool设置是否合理; 其中reloads列&#xff0c;表示对象被重新加载的次数&#xff0c;在一个设置合…...

应用案例 | 基于三维视觉的汽车零件自动化拧紧解决方案

​Part.1 引言 随着人们生活水平的提高&#xff0c;汽车作为理想的代步工具&#xff0c;逐渐成为人们生活中不可或缺的一部分。汽车的广泛应用&#xff0c;大大增加了汽车制造业的负荷。因此&#xff0c;如何提高生产效率和汽车性能&#xff0c;成为汽车制造业的首要关注话题。…...

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&#xff1a;static_cast(expression) const_cast dynamic_cast reinterpret_cast C 提供以下几类转换 static_cast&#xff1a;static_cast<type-id>(expression) tatic_cast 主要用于以下几种情况&#xff1a; 用于显式地将一个表达式转换为另一…...

【python、opencv】opencv仿射变换原理及代码实现

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

mac本地部署stable-diffusion

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

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 之后参照&#xff1a;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

每次谈到容器的时候&#xff0c;除了Docker之外&#xff0c;都会说起 Kubernetes&#xff0c;那么什么是 Kubernetes呢&#xff1f;今天就来一起学快速入门一下 Kubernetes 吧&#xff01;希望本文对您有所帮助。 Kubernetes&#xff0c;一种用于管理和自动化云中容器化工作负…...

YOLOv6 学习笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、YOLOv6贡献和改进二、YOLOv6核心概念三、YOLOv6架构改进四、YOLOv6重参思想五、YOLOv6的损失函数总结 前言 在计算机视觉领域&#xff0c;目标检测技术一直…...

paypal贝宝怎么绑卡支付

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

活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新

2023年11月28日&#xff0c;德州仪器(TI)嵌入式技术创新发展研讨会在上海顺利举办。作为TI中国第三方IDH&#xff0c;深圳市信驰达科技有限公司受邀参加&#xff0c;并设置展位&#xff0c;展出CC2340系列低功耗蓝牙模块及TPMS、蓝牙数字钥匙解决方案&#xff0c;与众多业内伙伴…...

Vue 循环走马灯

1、使用 transform: translateX()&#xff0c;循环将滚动内容在容器内偏移&#xff0c;超出容器部分隐藏&#xff1b; 2、避免滚动到末尾时出现空白&#xff0c;需要预留多几个。 3、一次循环偏移的距离scrollLoopWidth 可能受样式影响需要做些微调&#xff0c;比如单个item的…...

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux文件管理(3)》(27)

《Linux操作系统原理分析之Linux文件管理&#xff08;3&#xff09;》&#xff08;27&#xff09; 8 Linux文件管理8.6 文件管理和操作8.6.1 系统对文件的管理8.6.2 进程对文件的管理 8 Linux文件管理 8.6 文件管理和操作 8.6.1 系统对文件的管理 Linux 系统把所有打开的活动…...

【华为数据之道学习笔记】3-2 基础数据治理

基础数据用于对其他数据进行分类&#xff0c;在业界也称作参考数据。基础数据通常是静态的&#xff08;如国家、币种&#xff09;&#xff0c;一般在业务事件发生之前就已经预先定义。它的可选值数量有限&#xff0c;可以用作业务或IT的开关和判断条件。当基础数据的取值发生变…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

stm32G473的flash模式是单bank还是双bank?

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

MMaDA: Multimodal Large Diffusion Language Models

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

跨链模式:多链互操作架构与性能扩展方案

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

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#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日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

基于Springboot+Vue的办公管理系统

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