如何高效利用Spring中的@Cacheable注解?
在现代软件开发中,缓存是提升应用性能的重要手段。Spring框架提供了@Cacheable注解,帮助开发者轻松实现缓存机制。今天我们就来详细聊聊@Cacheable注解的使用,看看它是如何让我们的应用更加高效的!
@Cacheable注解的核心功能是缓存方法的返回结果。当我们标注一个方法为@Cacheable后,Spring会在该方法执行时自动检查缓存中是否已有结果。如果缓存中存在结果,Spring会直接返回这个结果,而不必执行方法。如果缓存中没有结果,Spring会执行方法,并将返回值存入缓存。这种机制大大减少了重复计算的开销,提升了性能。
我们先来看一下@Cacheable注解的基本用法。这个注解可以应用在类的方法上,比如一个服务类中的查询方法。使用时,我们只需简单地在方法上添加@Cacheable注解,并指定一个缓存名称。例如:
@Cacheable("users")
public User getUserById(Long id) {// 模拟数据库查询return userRepository.findById(id);
}
在这个例子中,当调用getUserById方法时,Spring会首先检查“users”缓存。如果缓存中有对应id的用户,Spring会直接返回这个用户;如果没有,方法会被执行,查询数据库并将结果存入缓存中。
当然,@Cacheable注解并不仅仅是如此简单。它还有很多高级功能,可以帮助我们更好地控制缓存行为。比如,我们可以通过key属性自定义缓存的键。默认情况下,Spring会使用方法的参数作为缓存的键,但我们可以根据自己的需求进行调整。例如:
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {return userRepository.findById(id);
}
在这个例子中,我们显式地指定了缓存的键为id。这样做的好处是,我们可以根据需要更改键的生成策略,从而避免潜在的键冲突。
除了key,@Cacheable注解还支持条件判断。我们可以使用condition属性指定何时缓存结果。例如,我们可以只在用户的id大于100时才缓存结果:
@Cacheable(value = "users", condition = "#id > 100")
public User getUserById(Long id) {return userRepository.findById(id);
}
这样做可以帮助我们避免缓存一些不必要的结果,节省内存和计算资源。
当然,@Cacheable注解的功能不仅限于基本的缓存操作。它还支持设置缓存的过期时间。通过使用Spring的缓存抽象,我们可以配置缓存的存活时间、最大数量等属性,来有效管理缓存的性能。例如,我们可以使用Ehcache、Redis等缓存实现,来满足不同的需求。
下面来看看如何使用Redis作为缓存,实现@Cacheable功能。首先,我们需要在Spring配置文件中添加Redis的相关配置。然后在Spring Boot应用程序中使用@EnableCaching注解启用缓存功能。接着,我们可以简单地使用@Cacheable注解来实现缓存。例如:
@Cacheable(value = "users")
public User getUserById(Long id) {return userRepository.findById(id);
}
当我们使用了Redis作为缓存提供者后,Spring会自动将查询结果存入Redis中,而不是内存中。这样可以实现更高效的分布式缓存方案。
再说说@Cacheable注解的失效策略。在某些情况下,我们可能需要清除缓存。Spring提供了@CacheEvict注解,可以帮助我们实现这个功能。比如说,当我们更新用户信息时,希望清除缓存中对应的用户数据。可以这样做:
@CacheEvict(value = "users", key = "#user.id")
public void updateUser(User user) {userRepository.save(user);
}
在上面的代码中,updateUser方法会在执行后清除缓存中对应id的用户数据,确保下次调用getUserById时会重新查询数据库。
@Cacheable注解的灵活性和强大功能让它成为了开发者的得力工具。通过合理配置,它不仅能够提升应用的性能,还能为我们提供更好的用户体验。无论是简单的缓存需求,还是复杂的分布式缓存策略,@Cacheable都能轻松应对。
在使用@Cacheable时,我们还需要注意一些最佳实践。比如,尽量避免将@Cacheable注解应用于修改数据的方法,因为缓存的存在可能导致数据不一致。此外,要考虑缓存的大小和过期策略,以避免内存溢出或过期数据的影响。
此外,@Cacheable注解在多线程环境下也需要小心使用。在高并发的场景中,多个线程可能同时请求相同的缓存数据。Spring会确保在缓存未命中时只执行一次方法,但仍需注意缓存的线程安全和数据一致性。
通过合理使用@Cacheable注解,我们可以在Spring应用中实现高效的缓存机制,提升整体性能!希望这篇文章能给你带来一些启发,帮助你更好地利用Spring的缓存功能!如果你有任何问题,欢迎随时交流!
相关文章:
如何高效利用Spring中的@Cacheable注解?
在现代软件开发中,缓存是提升应用性能的重要手段。Spring框架提供了Cacheable注解,帮助开发者轻松实现缓存机制。今天我们就来详细聊聊Cacheable注解的使用,看看它是如何让我们的应用更加高效的! Cacheable注解的核心功能是缓存方…...
Qt 进度条与多线程应用、基于 Qt 的文件复制工具开发
练习1:Qt 进度条与多线程应用 题目描述 开发一个基于 Qt 的应用程序,该应用程序包含一个水平进度条(QSlider),并且需要通过多线程来更新进度条的值。请根据以下要求完成代码: 界面设计: 使用 QS…...
软件工程---构件
在软件工程中,构件是一个独立的、可复用的软件单元,它具有明确的功能、接口和行为,并且可以在不同的环境中加以集成和复用。构件的概念是软件架构和组件化开发的核心思想之一,其目的是促进软件系统的模块化、可维护性和可扩展性。…...
【算法 C/C++】二维差分
2025 - 03 - 08 - 第 71 篇 Author: 郑龙浩 / 仟濹 【二维差分】 文章目录 前缀和与差分 - 我的博客差分(二维)1 大体思路 | 一些区间加某数的最终结果2 二维差分原理3 例题 前缀和与差分 - 我的博客 一维前缀和 【算法 C/C】一维前缀和 一维差分 【算法 C/C】一维差分 二维前…...
灰色地带规避:知识产权校验API的商标库模糊匹配算法
在反向海淘或其他电商业务场景中,为了规避知识产权方面的灰色地带,开发知识产权校验 API 并运用商标库模糊匹配算法是很有必要的。以下将详细介绍商标库模糊匹配算法的设计与实现: 算法设计思路 商标库模糊匹配算法的核心目标是在给定一个待匹…...
LINUX网络基础 [五] - HTTP协议
目录 HTTP协议 预备知识 认识 URL 认识 urlencode 和 urldecode HTTP协议格式 HTTP请求协议格式 HTTP响应协议格式 HTTP的方法 HTTP的状态码 编辑HTTP常见Header HTTP实现代码 HttpServer.hpp HttpServer.cpp Socket.hpp log.hpp Makefile Web根目录 H…...
嵌入式人工智能应用-第6章 人脸检测
嵌入式人工智能应用 人脸检测 嵌入式人工智能应用1 人脸检测1.1 CNN 介绍1.2 人脸检测原理1.3 MTCNN介绍1.4 NCNN介绍2 系统安装2.1 安装依赖库NCNN2.2 运行对应的库3 总结1 人脸检测 1.1 CNN 介绍 卷积神经网络。卷积是什么意思呢?从数学上说,卷积是一种运算。它是我们学习…...
编程考古-Borland历史:《.EXE Interview》对Anders Hejlsberg关于Delphi的采访内容(中)
为了纪念Delphi在2002年2月14日发布的25周年(2020.2.12),这里有一段由.EXE杂志编辑Will Watts于1995年对Delphi首席架构师Anders Hejlsberg进行的采访记录。在这次采访中,Anders讨论了Delphi的设计与发展,以及即将到来的针对Windows 95的32位版本。 Q. 编译器引擎本身是用…...
redis数据类型以及底层数据结构
redis数据类型以及底层数据结构 String:字符串类型,底层就是动态字符串,使用sds数据结构 Map:有两种数据结构:1.压缩列表:当hash结构中存储的元素个数小于了512个。并且元 …...
C运算符 对比a++、++a、b--、 --b
#include<stdio.h> int main() { int a 21;int b 10;int c, d;c a;//先赋值给c,a本身再运算 c 21, a 22;//c a;//a本身先运算,再赋值给c a 22,c 22;printf("c %d, a %d\n",c, a); d --b;//b本身先运算,再赋值给d …...
Java EE 进阶:Spring MVC(2)
cookie和session的关系 两者都是在客户端和服务器中进行存储数据和传递信息的工具 cookie和session的区别 Cookie是客⼾端保存⽤⼾信息的⼀种机制. Session是服务器端保存⽤⼾信息的⼀种机制. Cookie和Session之间主要是通过SessionId关联起来的,SessionId是Co…...
基于Matlab的人脸识别的二维PCA
一、基本原理 传统 PCA 在处理图像数据时,需将二维图像矩阵拉伸为一维向量,这使得数据维度剧增,引发高计算成本与存储压力。与之不同,2DPCA 直接基于二维图像矩阵展开运算。 它着眼于图像矩阵的列向量,构建协方差矩阵…...
Java 深度复制对象:从基础到实战
目录 一、深度复制的概念二、实现深度复制的方法1. 使用序列化2. 手动实现深度复制 三、总结 在 Java 编程中,对象的复制是一个常见的需求。然而,简单的复制操作(如直接赋值)只会复制对象的引用,而不是创建一个新的对象…...
【Java开发指南 | 第三十五篇】Maven + Tomcat Web应用程序搭建
读者可订阅专栏:Java开发指南 |【CSDN秋说】 文章目录 前言Maven Tomcat Web应用程序搭建1、使用Maven构建新项目2、单击项目,连续按两次shift键,输入"添加",选择"添加框架支持"3、选择Java Web程序4、点击&…...
TCP三次握手,四次挥手;多进程、多线程实现并发服务器
三次握手,四次挥手 三次握手示意图: SYN、ACK是TCP协议头里面的标志位 同步 SYN:仅在三次握手建立 TCP 连接时有效。当 SYN 1 而 ACK 0 时,表明这是一个连接请求报文段,对方若同意建立连接,则应在相应的…...
Java基础系列:深入理解八大基本数据类型及避坑指南
目录 一、基本数据类型概述 八大类型速查表 二、各类型详解与常见陷阱 1. 整型家族(byte/short/int/long) 2. 浮点型(float/double) 3. 字符型(char) 4. 布尔型(boolean) 三…...
【Gaussian Model】高斯分布模型
目录 高斯分布模型用于异常检测(Gaussian Model for Anomaly Detection)1. 高斯分布简介2. 高斯分布模型用于异常检测(1) 训练阶段:估计数据分布(2) 检测阶段:计算概率判断异常点 3. 示例代码4. 高斯分布异常检测的优缺点优点缺点…...
Unity--Cubism Live2D模型使用
了解LIVE2D在unity的使用--前提记录 了解各个组件的作用 Live2D Manuals & Tutorials 这些文件都是重要的控制动画参数的 Cubism Editor是编辑Live2D的工具,而导出的数据的类型,需要满足以上的条件 SDK中包含的Cubism的Importer会自动生成一个Pref…...
Day4 C语言与画面显示练习
文章目录 1. harib01a例程2. harib01b例程3. harib01e例程4. harib01f例程5. harib01h例程 1. harib01a例程 上一章主要是将画面搞成黑屏,如果期望做点什么图案,只需要再VRAM里写点什么就好了,使用nask汇编语言实现一个函数write_mem8&#…...
【redis】全局命令exists、del、expire、ttl(惰性删除和定期删除)
exists——判定 key 是否存在 语法: exists key [key...] # 返回值:key 存在的个数针对多个 key 来说,是非常有用的时间复杂度 O ( 1 ) O(1) O(1) Redis 组织这些 key 就是按照哈希表的方式来组织的。Redis 支持很多数据结构指的是 value …...
VUE3项目的文档结构分析
1. Vue 3 项目的文档结构 Vue 3 项目通常基于 Vue CLI 或 Vite 等工具创建,其文档结构如下: 常见目录结构 my-vue-project/ ├── public/ # 静态资源目录 │ ├── index.html # 入口页面 ├── src/ …...
Linux笔记---自定义shell
目录 前言 1. 程序框架 2. 打印命令行提示符 2.1 获取用户名(GetUserName) 2.2 获取主机名(GetHostName) 2.3 获取工作目录(GetPwd) 3. 获取命令行输入 4. 判断是否有重定向 5. 解析命令行 6. 内建命令 6.1 内建命令的特点 6.2 常见内建命令 6.3 内建命令 vs 外部命…...
步进电机软件细分算法解析与实践指南
1. 步进电机细分技术概述 步进电机是一种将电脉冲信号转换为角位移的执行机构,其基本运动单位为步距角。传统步进电机的步距角通常为 1.8(对应 200 步 / 转),但在高精度定位场景下,这种分辨率已无法满足需求。细分技术…...
mapbox开发小技巧
自定义图标 // 1、单个图标 const url ./static/assets/symbols/code24x24/VIDEO.png // 图标路径 map.loadImage(url ,(error, image) > {if (error) throw errormap.addImage(video-icon, image) })// 2、雪碧图利用canvas // json和png图片 function getStyleImage(fil…...
ApoorvCTF Rust语言逆向实战
上周参加了国外的比赛,名称叫:ApoorvCTF 看一下老外的比赛跟我们有什么不同,然后我根据国内比赛对比发现,他们考点还是很有意思的,反正都是逆向,哈哈哈 Rusty Vault 题目描述: In the heart…...
IntersectionObserver接口介绍
IntersectionObserver API 是浏览器提供的一个用于异步观察目标元素与其祖先元素或视口(Viewport)交叉状态(即是否进入或离开视口)的接口。在 IntersectionObserver 出现之前,开发者通常需要通过监听 scroll 事件或使用…...
AI壁纸进阶宝典:让创作效率与质量飞速提升的法门
在数字化创意浪潮席卷的当下,AI壁纸以其独特魅力和无限可能,吸引了众多设计爱好者和专业设计师的目光。然而,如何在众多创作者中脱颖而出,打造令人惊艳的AI壁纸呢?本文将从基础到进阶,全方位剖析AI壁纸创作…...
Releases(发布) 和 版本管理 是两个紧密相关的概念
在软件开发和维护中,Releases(发布) 和 版本管理 是两个紧密相关的概念,特别是在开源项目或企业软件开发中。 1. Releases(发布) Release 是指软件的一个正式发布版本,通常经过开发、测试、修复 Bug,并被认为是足够稳定和可用于生产环境的版本。 主要特点 里程碑:通…...
从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十二) socketio 消息处理
1.后端 在message.controller.js中 在sendMessage方法中 每当我们发送消息 需要socketio把这个消息转发给 接收人 加入转发逻辑 // 把消息发给指定的用户的socket const receiverSocketId getReceiverSocketId(receiverId); if(receiverSocketId) { io.to(receiverSocket…...
【运维篇】KubeSphere-02(经验汇总)
一、使用建议 1.对于数据库、对像存储比较重的要不能丢失,有异地存储备份需求的有状态服务,不建议采用k8s进行部署,会导致运维难度更大。 2.对于中间件如redis、MQ、harbor、seata、nacos、zookeeper可采用k8s部署。 3.对于无状态服务tomc…...
8.大模型微调学习案例:基于 Hugging Face、8位量化与 LoRA 适配器的方案
文章目录 一、引言二、数据预处理与构建数据集2.1 加载 JSON 数据2.2 构造训练样本2.3 构建 Hugging Face 数据集与分词2.4 添加标签字段2.5 划分训练集与验证集 三、模型加载、量化与适配器配置3.1 配置设备与显存使用3.2 配置 8 位量化3.3 加载预训练模型并映射设备3.4 为 8 …...
用分页干掉显存浪费!聊聊VLLM的PagedAttention
不知道你在部署模型的时候,有没有经历过这样的抓狂时刻——跑大模型时显卡显存明明没有占满,程序却报错OOM(内存不足)?表面看是显存不足,背后其实是KVCache碎片化和重复存储这个"隐形刺客"在作祟…...
Python——地图可视化
分级统计地图:一般使用同一种颜色表示一个区域的属性,常用与选举和人口普查数据的可视化。对于颜色的选择可以使用单色渐变系、双向渐变系、完整色谱变化。 使用这类颜色渐变进行填充存在的问题: 使用这类方法适用于数据密集分布的区域&#…...
3.8【Q】cv
这个draw_line函数的逻辑和功能是什么?代码思路是什么?怎么写的? 这个t是什么?t.v[0]和t.v[1],[2]又是什么? void rst::rasterizer::draw(rst::pos_buf_id pos_buffer, rst::ind_buf_id ind_buffer, rst::Primitive ty…...
LeetCode 热题 100_字符串解码(71_394_中等_C++)(栈)
LeetCode 热题 100_字符串解码(71_394) 题目描述:输入输出样例:题解:解题思路:思路一(栈): 代码实现代码实现(栈):以思路一为例进行调…...
基于大模型预测的新型隐球菌脑膜炎综合诊疗研究报告
目录 一、引言 1.1 研究背景与目的 1.2 研究现状综述 二、大模型预测原理及数据基础 2.1 大模型技术简介 2.2 数据收集与预处理 2.3 模型训练与验证 三、术前风险预测与准备 3.1 病情评估指标确定 3.2 手术方案制定 3.3 麻醉方案规划 四、术中监测与应对 4.1 实时…...
SQL Server核心知识总结
SQL Server核心知识总结 🎯 本文总结了SQL Server核心知识点,每个主题都提供实际可运行的示例代码。 一、SQL Server基础精要 1. 数据库核心操作 -- 1. 创建数据库(核心配置) CREATE DATABASE 学生管理系统 ON PRIMARY (NAME 学生管理系统…...
浏览器WEB播放RTSP
注意:浏览器不能直接播放RTSP,必须转换后才能播放。这一点所有的播放都是如此。 参考 https://github.com/kyriesent/node-rtsp-stream GitHub - phoboslab/jsmpeg: MPEG1 Video Decoder in JavaScript 相关文件方便下载 https://download.csdn.net…...
登录固定账号和密码:
接口文档 【apifox】面试宝典 个人中心-保存用户数据信息 - 教学练测项目-面试宝典-鸿蒙 登录固定账号和密码: 账号:hmheima 密码:Hmheima%123 UI设计稿 【腾讯 CoDesign】面试宝典 CoDesign - 腾讯自研设计协作平台 访问密码࿱…...
深度学习/强化学习调参技巧
深度调优策略 1. 学习率调整 技巧:学习率是最重要的超参数之一。过大可能导致训练不稳定,过小则收敛速度慢。可以使用学习率衰减(Learning Rate Decay)或自适应学习率方法(如Adam、RMSprop)来动态调整学习…...
Java常用正则表达式(身份证号、邮箱、手机号)格式校验
目录 身份证号的正则表达式 代码解释 正则表达式 方法 isValidIDCard 注意事项 校验邮箱的正则表达式 代码解释 正则表达式 方法 isValidEmail 注意事项 手机号的正则表达式 中国大陆手机号校验(支持空字符串) 代码解释 通用手机号校验&am…...
1.12.信息系统的分类【ES】
专家系统(ES)技术架构深度解析 一、ES核心定义 🧠 智能决策中枢 由三大核心能力构建的领域专家模拟系统: 存储专家级领域知识(10^4规则量级)支持不确定性推理(置信度>85%)动态…...
c语言程序设计--(结构体、共用体)冲刺考研复试中的面试问答,来看看我是怎么回答的吧!
结构体 1、谈谈你对结构体的理解。 答,首先在结构的基础知识上,结构是一些值的集合,这些值称为成员变量结构的每个成员可以是不同类型的变量。结构体其实就是把(一些单一类型的数据)不同类型的数据组合在一起的做法便…...
闭包:JavaScript 中的隐形大杀器
你可能已经在很多地方听说过闭包这个词,尤其是涉及到 JavaScript 的作用域和异步操作时。闭包是 JavaScript 中非常核心的概念,然而它又非常容易让开发者感到困惑。今天我们就来深入剖析闭包,帮助你真正理解它的工作原理,以及如何…...
分布式锁—7.Curator的分布式锁一
大纲 1.Curator的可重入锁的源码 2.Curator的非可重入锁的源码 3.Curator的可重入读写锁的源码 4.Curator的MultiLock源码 5.Curator的Semaphore源码 1.Curator的可重入锁的源码 (1)InterProcessMutex获取分布式锁 (2)InterProcessMutex的初始化 (3)InterProcessMutex.…...
linux---天气爬虫
代码概述 这段代码实现了一个天气查询系统,支持实时天气、未来天气和历史天气查询。用户可以通过终端菜单选择查询类型,并输入城市名称来获取相应的天气信息。程序通过 TCP 连接发送 HTTP 请求,并解析返回的 JSON 数据来展示天气信息。 #in…...
C++蓝桥杯基础篇(九)
片头 嗨!小伙伴们,大家好~ 今天我们将学习蓝桥杯基础篇(十),学习函数相关知识,准备好了吗?咱们开始咯! 一、函数基础 一个典型的函数定义包括以下部分:返回类型、函数名…...
Java Spring MVC (2)
常见的Request Controller 和 Response Controller 的区别 用餐厅点餐来理解 想象你去一家餐厅吃饭: Request Controller(接单员):负责处理你的点餐请求,记录你的口味、桌号等信息。Response Controller(…...
Elasticsearch:使用 BigQuery 提取数据
作者:来自 Elastic Jeffrey Rengifo 了解如何使用 Python 在 Elasticsearch 中索引和搜索 Google BigQuery 数据。 BigQuery 是 Google 的一个平台,允许你将来自不同来源和服务的数据集中到一个存储库中。它还支持数据分析,并可使用生成式 AI…...
接口-菜品分页查询
业务内容 页面上菜品根据菜品名称、菜品分类、售卖状态三个字段进行分页查询。 在请求参数中携带了菜品名称、菜品分类、售卖状态三个字段参数。 返回PageResult类型的实体。 注意:在返回数据中在records下有个categoryName,这个字段的内容在category…...