Springboot 缓存@Cacheable 使用


文章目录

  • 前言
  • 一、@Cacheable 是什么?
  • 二、Springboot 项目中如何使用
    • 2.1 基于内存实现:
      • 2.1.1 Cacheable 引入并使用:
      • 2.1.2 Cacheable 配置参数
    • 2.2 Cacheable 基于redis 缓存
    • 2.3 @Cacheable 注解属性
  • 总结

前言


一、@Cacheable 是什么?

@Cacheable 是 Spring 缓存抽象的核心注解,作用是将方法的返回结果缓存起来:

  • 当第一次调用该方法时,执行方法体并将返回值存入缓存;
  • 后续使用「相同参数」调用时,直接从缓存获取结果,无需执行方法体;
  • 本质是「方法级缓存」,基于「键值对」存储(键:方法名 + 参数;值:方法返回值);
  • 适用场景:查询类方法(如根据 ID 查用户、查商品详情),数据变更频率低、查询频率高。

二、Springboot 项目中如何使用

2.1 基于内存实现:

2.1.1 Cacheable 引入并使用:

(1) 引入缓存依赖
在 pom.xml(Maven)中添加 Spring 缓存启动器(Gradle 同理):

<!-- Spring Cache Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- Caffeine 缓存实现 --><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId></dependency>

(2)开启缓存功能
在 SpringBoot 启动类上添加 @EnableCaching 注解,全局开启缓存支持:

importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cache.annotation.EnableCaching;@SpringBootApplication@EnableCaching// 核心:开启缓存publicclassCacheDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(CacheDemoApplication.class,args);}}

(3)在查询方法上添加 @Cacheable
在 Service/Controller 的查询方法上标注 @Cacheable,指定缓存名称(必填):

importorg.springframework.cache.annotation.Cacheable;importorg.springframework.stereotype.Service;@ServicepublicclassUserService{// cacheNames:缓存名称(必填,相当于缓存的“命名空间”)@Cacheable(cacheNames="userCache")publicUsergetUserById(Longid){// 模拟数据库查询(首次调用执行,后续从缓存获取)System.out.println("执行数据库查询,用户ID:"+id);returnnewUser(id,"张三",20);}// 模拟用户实体类(需有 getter/setter,Lombok 可简化)publicstaticclassUser{privateLongid;privateStringname;privateIntegerage;publicUser(Longid,Stringname,Integerage){this.id=id;this.name=name;this.age=age;}// getter/setter 省略(实际开发用 @Data 注解)publicLonggetId(){returnid;}publicStringgetName(){returnname;}publicIntegergetAge(){returnage;}}}

(4) 更新缓存:

// 修改用户后更新缓存(key 需与 @Cacheable 一致)@CachePut(cacheNames="userCache",key="#user.studentId")publicStudentDtoupdateUser(StudentDtouser){System.out.println("更新用户:"+user.getStudentId());returnuser;}

(5) 删除缓存:

// 删除用户后清理缓存@CacheEvict(cacheNames="userCache",key="#id")publicvoiddeleteUser(Stringid){System.out.println("删除用户:"+id);}// 清空整个 userCache 缓存@CacheEvict(cacheNames="userCache",allEntries=true)publicvoidclearUserCache(){System.out.println("清空用户缓存");}

2.1.2 Cacheable 配置参数

spring:cache:type:caffeine# 指定缓存类型为 Caffeine(替代默认的 ConcurrentHashMap/Redis)caffeine:spec:initialCapacity=100,maximumSize=1000,expireAfterWrite=10s# Caffeine 核心参数
  • initialCapacity:缓存初始容量(100):缓存初始化时的容器大小,避免频繁扩容导致性能损耗
  • maximumSize:缓存最大容量(1000):缓存条目数超过 1000 时,会按 LRU 策略淘汰旧数据
  • expireAfterWrite:写入后过期时间(10s):缓存条目创建 / 更新后,10 秒未访问则自动过期

2.2 Cacheable 基于redis 缓存

SpringBoot 默认使用「内存缓存(ConcurrentHashMap)」,重启后缓存丢失,此时可以切换为 Redis:

(1) 引入依赖:

<!-- redis jar--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.5</version></dependency>

(2)配置项:

spring:cache:type:redisredis:# 1. 全局过期时间(核心,替代 Caffeine 的 expireAfterWrite)time-to-live:1000s# 所有缓存默认 10 秒过期(支持 s/m/h/d)# 3. 是否缓存空值(防止缓存穿透)cache-null-values:true# 4. 缓存 key 前缀(避免不同业务 key 冲突)key-prefix:"cache:"# 5. 是否使用前缀(建议开启)use-key-prefix:truedata:redis:host:localhostport:6379timeout:120000database:1lettuce:pool:max-active:50max-idle:8max-wait:-1min-idle:1

(3) 测试结果:

@Override// 使用缓存@Cacheable(cacheNames="userCache",key="#root.args[0]")publicStudentDtogetStudentById(StringstudentId){log.info("getStudentById:{}",studentId);StudentDtodto=StudentDto.builder().studentId(studentId).studentAge(12).studentName("test").studentSex("man").build();returndto;}

redids 缓存结果

2.3 @Cacheable 注解属性

(1) 注解属性:

@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic@interfaceCacheable{// 核心属性(按使用频率排序)String[]value()default{};// 等价于 cacheNames,缓存名称(必填)String[]cacheNames()default{};// 缓存名称(必填,和 value 二选一,推荐用这个)Stringkey()default"";// 自定义缓存键(SpEL 表达式)StringkeyGenerator()default"";// 自定义键生成器(与 key 互斥)StringcacheManager()default"";// 指定缓存管理器(多缓存源时用)StringcacheResolver()default"";// 自定义缓存解析器(比 cacheManager 更灵活)Stringcondition()default"";// 缓存条件(满足则缓存,SpEL)Stringunless()default"";// 排除条件(满足则不缓存,SpEL)booleansync()defaultfalse;// 是否同步缓存(解决缓存击穿)}
  • cacheNames: 定义缓存的「命名空间」,区分不同业务的缓存(如用户缓存、订单缓存),必填属性;每个 cacheNames 对应一个独立的缓存容器(如 Caffeine 中的一个 Cache 实例、Redis 中的一个 key 前缀);不能省略,否则 Spring 会抛出「cacheNames/value 不能为空」异常。
  • key(自定义缓存键,SpEL 表达式)自定义缓存的 key,替代默认的「方法名 + 所有参数组合」,灵活控制缓存粒度;默认规则:若不指定 key,Spring 会用 KeyGenerator 生成默认 key(格式:方法全限定名::参数1=值1,参数2=值2);可以使用SpEL 灵活定义缓存的key值

(2) redis key 生成策略:

SpEL 表达式含义示例
#参数名引用方法参数key = “#id”
#参数.属性引用参数对象的属性key = “#user.id”
#result引用方法返回值(仅 condition/unless 生效)key = “#result.id”(不推荐)
#root根对象,包含方法 / 参数等信息key = “#root.methodName + #id”

代码示例:

// 仅以 id 为键(忽略其他参数)@Cacheable(cacheNames="userCache",key="#id")publicUsergetUserById(Longid,StringunusedParam){...}// 以参数对象的属性为键@Cacheable(cacheNames="userCache",key="#user.id + '_' + #user.name")publicUsergetUserByUser(Useruser){...}// 结合根对象:方法名 + 参数(避免不同方法的相同参数冲突)@Cacheable(cacheNames="userCache",key="#root.methodName + '_' + #id")publicUsergetUserById(Longid){...}

(3) 条件控制属性
condition(缓存条件,SpEL 表达式) 作用:仅当表达式结果为 true 时,才将方法结果存入缓存; 执行时机:方法执行后、存入缓存前

// 仅当 id > 0 时缓存(参数条件)@Cacheable(cacheNames="userCache",key="#id",condition="#id > 0")publicUsergetUserById(Longid){...}// 仅当返回值 age > 18 时缓存(返回值条件)@Cacheable(cacheNames="userCache",key="#id",condition="#result.age > 18")publicUsergetUserById(Longid){...}// 多条件组合(参数 id > 0 且返回值不为 null)@Cacheable(cacheNames="userCache",key="#id",condition="#id > 0 and #result != null")publicUsergetUserById(Longid){...}

unless(排除缓存条件,SpEL 表达式)作用:与 condition 相反,当表达式结果为 true 时,不 缓存结果;执行时机:方法执行后、存入缓存前;核心场景:排除 null 值(避免缓存穿透)、排除异常结果等;

// 不缓存 null 值(解决缓存穿透)@Cacheable(cacheNames="userCache",key="#id",unless="#result == null")publicUsergetUserById(Longid){if(id==999L)returnnull;// 不缓存returnnewUser(id,"张三",20);// 缓存}// 不缓存 age <= 18 的用户@Cacheable(cacheNames="userCache",key="#id",unless="#result.age <= 18")publicUsergetUserById(Longid){...}

(4)sync(同步缓存,解决缓存击穿)
作用:开启同步模式,当缓存未命中时,多个并发请求只会有一个请求执行方法体,其余请求等待缓存生成(解决热点 key 缓存击穿);默认值:false(非同步,多个请求同时执行方法体);

// 开启同步缓存,解决缓存击穿@Cacheable(cacheNames="userCache",key="#id",sync=true)publicUsergetUserById(Longid){...}

注意:
① sync=true 时,unless 属性失效(无法基于返回值排除缓存);
② 仅适用于本地缓存(Caffeine),分布式缓存(Redis)需结合分布式锁使用


总结

本文记录Springboot 缓存@Cacheable 的引入和使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1201197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026 运动鞋品牌科普新篇:五大专业标杆的技术革新与选购指南

​一、2026 运动鞋行业:三大新趋势引领消费变革 2026 年,全球运动鞋市场规模预计突破 2800 亿美元,行业发展呈现三大核心新趋势:一是技术场景化融合,不再是单一技术堆砌,而是针对具体运动场景实现 “技术精准匹配…

风力发电的调研报告

三&#xff0e;风力发电机的分类 根据基本结构以及运行原理&#xff0c;发电机通常可分为直流电机、感应异步电机和同步电机几大类。风力发电系统中电机类型繁多&#xff0c;包括以下类型。 &#xff08;一&#xff09;在CSCF 风电系统中常用的发电机包括异步机感应电机和电励磁…

基于Java+SpringBoot+SSM幼儿园管理系统(源码+LW+调试文档+讲解等)/幼儿园管理软件/幼儿园管理平台/幼儿园信息化系统/幼儿园教务系统/幼儿园管理系统软件/幼儿园管理解决方案

博主介绍 &#x1f497;博主介绍&#xff1a;✌全栈领域优质创作者&#xff0c;专注于Java、小程序、Python技术领域和计算机毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2025-2026年最新1000个热门Java毕业设计选题…

靠谱的电动冲浪板品牌,太酷了吧!

在水上运动的世界里,电动冲浪板正以一种酷炫的姿态吸引着众多爱好者的目光。想象一下,在湛蓝的海面上,冲浪者踩着电动冲浪板,风驰电掣般地穿梭,那场景简直太酷了!今天,我们就来深入探讨一下靠谱的电动冲浪板品牌…

双目三维重建的步骤与核心算法

双目三维重建的步骤与核心算法 双目三维重建是模拟人类双眼视觉原理,通过两个固定位置的相机拍摄同一场景,利用视差计算三维坐标的技术,广泛应用于机器人导航、自动驾驶、三维建模等领域。其流程可分为六大核心步骤…

2026年变压器绕组变形测试仪知名品牌实力对比与战略选购指南

在全球能源转型与新型电力系统建设加速的宏观背景下,电力设备的状态检测与智能运维已从“可选”升级为“必选”。变压器作为电网的核心资产,其绕组的机械健康状况直接关系到整个电网的稳定与安全。变压器绕组变形测试…

别再凑字数!宏智树 AI 教你把课程论文写成 “高分范本”

作为深耕论文写作科普的教育博主&#xff0c;每到期末就被学生们的课程论文难题包围&#xff1a;“选题要么太泛要么太偏&#xff0c;凑够字数都难”“文献堆了一堆&#xff0c;却不知道怎么整合出逻辑”“查重改到崩溃&#xff0c;结果还是被导师说‘缺乏思考’”…… 其实课程…

手动磨题 VS 智能生成?宏智树 AI 解锁问卷设计的学术高效范式

做社科实证论文时&#xff0c;你是否经历过这样的窘境&#xff1a;花一周时间翻文献、磨题项&#xff0c;设计出的问卷却被导师批 “信效度不足”&#xff1b;用普通表单工具生成问卷&#xff0c;又因题项诱导性强、逻辑混乱&#xff0c;导致回收的数百份数据沦为 “无效样本”…

vtb|blog|auto

这周在尝试一些事情&#xff0c;做新东西的感觉很刺激很开心&#xff0c;但一天下来就感觉脑子像被打了一样… vtb 模型整合的差不多了…还有一些小问题 不知道什么时候可以做好 随缘吧 好了应该会用小号在b站上播着玩玩个人网站 博客网站写的 简单-花哨-简单-花哨… 还在寻找一…

2026液氮速冻机市场盘点:哪些品牌更受青睐?液氮/制氧机/汽化器/液氮速冻机/真空管/液氩,液氮速冻机厂商找哪家

在消费升级与食品安全标准日益提升的背景下,食品工业对加工技术的要求不断攀高。液氮速冻技术,以其极速冷冻(-196℃)、最大程度锁住食材原鲜、抑制微生物活动及有效减少细胞冰晶损伤等显著优势,正成为高端食品加工…

适合学生二次开发的轮式机器人需求深度分析与产品选型指南

随着人工智能与机器人技术的深度融合,高校在开展教学、竞赛及科研活动时,对轮式机器人底盘的二次开发需求呈现出显著的分层化与专业化趋势。学生开发的核心需求已从简单的遥控移动转向“感知-决策-执行”全链路的深度…

二氧化碳测试仪源头厂家有哪些?2026年优质供应商与知名厂家汇总

随着“双碳”战略的深入推进,碳捕集、利用与封存(CCUS)技术规模化应用,以及工业生产、医疗健康、暖通制冷、科研教学等领域对二氧化碳浓度监测的需求日益严苛,二氧化碳测试仪的市场需求持续攀升。源头厂家凭借自主…

科研绘图工具R语言

目录 前言&#xff1a; 一、下载软件 二、简单绘图 前言&#xff1a; 有的时候需要绘制复杂图形&#xff0c;但是你其实自己也不知道究竟有哪些可以绘制的图&#xff0c;除了散点图&#xff0c;折线图等等&#xff0c;下面就是有一个网站&#xff0c;上面有很多图形&#…

宏智树 AI:一键生成三类高分 PPT,学术职场汇报再也不踩坑

作为深耕论文写作科普的教育博主&#xff0c;后台被催更最多的内容&#xff0c;不是论文框架搭建&#xff0c;也不是参考文献排版&#xff0c;而是 “学术 PPT 到底怎么做”。从开题报告的思路阐述&#xff0c;到论文答辩的成果展示&#xff0c;再到职场的工作汇报&#xff0c;…

SAE J1939 转 Profinet 工业数据采集网关 实现全生命周期追溯 挖掘机运维效率升级

一、项目背景某工程机械制造商针对新一代智能液压挖掘机进行智能化升级&#xff0c;需解决设备动力系统、液压执行系统、电控操作系统之间的实时协同与精准控制难题。传统挖掘机采用机械式控制与离散式电控架构&#xff0c;发动机、液压泵、动臂/斗杆伺服执行机构数据孤立&…

四通道信息融合下的齿轮箱故障诊断(Python代码,SVM模型和CNN模型进行对比实验,解压缩即可运行,有详细中文注释)

1.效果运行视频&#xff1a;四通道信息融合下的齿轮箱故障诊断&#xff08;Python代码&#xff0c;SVM模型和CNN模型进行对比实验&#xff09;_哔哩哔哩_bilibili 用到的库&#xff1a; 2.数据集介绍&#xff1a;数据免费下载链接&#xff08;不要积分&#xff09;&#xff1a…

揭秘那些比较好的电动冲浪板厂家

超棒!揭秘那些比较好的电动冲浪板厂家 在水上运动的浪潮中,电动冲浪板正逐渐成为热门之选。它打破了传统冲浪对海浪的依赖,让更多人能在平静水域体验冲浪的乐趣。今天,我们就来深入了解一下电动冲浪板,同时揭秘那…

人工智能在设计领域的应用:从创意辅助到落地提效的实践路径

人工智能技术正在重构设计行业的底层逻辑&#xff0c;从创意萌发到落地执行&#xff0c;从团队协作到版权管理&#xff0c;AI的介入打破了专业壁垒&#xff0c;让设计从专业人士的专属变成全民可参与的创造性活动。这种变化不仅提升了设计效率&#xff0c;更拓展了设计的边界&a…

电动冲浪板哪家强?这个行业“宝藏厂家”别错过!

在水上运动的世界里,传统冲浪需依赖海浪,这大大限制了冲浪爱好者的发挥。而电动冲浪板的出现,彻底打破了这一限制,让冲浪不再受海浪条件的束缚,随时随地都能享受冲浪的乐趣。可面对市场上众多的电动冲浪板品牌,消…

从被动监控到主动预警:AI 行为识别实战,打造“看懂风险”的智能安防系统

文章目录 从0到1掌握行为识别:摔倒、运动、打架识别全流程实战指南 一、行为识别是什么?—— 让机器看懂“人类动作” 二、行为识别核心技术拆解 1. 两大技术路径:单帧与多帧的博弈 2. 经典模型架构:从C3D到I3D 三、实战:搭建摔倒识别系统 步骤1:数据集准备与标注 步骤2:…