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

Spring Boot项目@Cacheable注解的使用

@Cacheable 是 Spring 框架中用于缓存的注解之一,它可以帮助你轻松地将方法的结果缓存起来,从而提高应用的性能。下面详细介绍如何使用 @Cacheable 注解以及相关的配置和注意事项。

1. 基本用法

1.1 添加依赖

首先,确保你的项目中包含了 Spring Cache 的依赖。如果你使用的是 Spring Boot,可以在 pom.xmlbuild.gradle 中添加以下依赖:

Maven:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-cache'
1.2 启用缓存

在你的 Spring Boot 应用的主类或配置类上添加 @EnableCaching 注解,以启用缓存功能。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
1.3 使用 @Cacheable 注解

假设你有一个服务类 DataService,其中有一个方法 getSortedData 需要缓存其结果。你可以使用 @Cacheable 注解来实现这一点。

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;@Service
public class DataService {@Cacheable("sortedData")public TableDataInfo getSortedData(String param) {// 模拟耗时操作try {Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}// 返回模拟数据return new TableDataInfo();}
}

解释:

  • @Cacheable("sortedData"): 这个注解告诉 Spring 在调用 getSortedData 方法时,先检查名为 sortedData 的缓存中是否存在与参数 param 对应的结果。
    • 如果存在,则直接返回缓存中的结果,不再执行方法体。
    • 如果不存在,则执行方法体,将结果存入缓存中,并返回结果。
1.4 自定义缓存键

默认情况下,Spring 使用方法参数作为缓存键。如果你需要自定义缓存键,可以使用 key 属性。

@Cacheable(value = "sortedData", key = "#param")
public TableDataInfo getSortedData(String param) {// 方法体
}

解释:

  • key = "#param": 使用方法参数 param 作为缓存键。

你还可以使用 SpEL(Spring Expression Language)来构建更复杂的缓存键。

@Cacheable(value = "sortedData", key = "#param + '_' + #anotherParam")
public TableDataInfo getSortedData(String param, String anotherParam) {// 方法体
}

2. 配置缓存管理器

Spring 支持多种缓存实现,如 Caffeine、Ehcache、Redis 等。下面分别介绍如何配置这些缓存管理器。

2.1 使用 Caffeine 作为缓存实现
  1. 添加依赖:

    <dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId>
    </dependency>
    
  2. 配置 Caffeine:

    你可以在 application.ymlapplication.properties 中配置 Caffeine 的缓存参数。

    application.yml:

    spring:cache:type: caffeinecaffeine:spec: maximumSize=1000,expireAfterAccess=60s
    

    application.properties:

    spring.cache.type=caffeine
    spring.cache.caffeine.spec=maximumSize=1000,expireAfterAccess=60s
    
    • maximumSize=1000: 设置缓存的最大条目数为 1000。
    • expireAfterAccess=60s: 设置缓存条目在最后一次访问后的过期时间为 60 秒。
2.2 使用 Ehcache 作为缓存实现
  1. 添加依赖:

    <dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId>
    </dependency>
    
  2. 配置 Ehcache:

    创建一个 ehcache.xml 文件,并在其中定义缓存配置。

    ehcache.xml:

    <config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xmlns='http://www.ehcache.org/v3'xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd"><cache alias="sortedData"><key-type>java.lang.String</key-type><value-type>com.ruoyi.common.core.page.TableDataInfo</value-type><resources><heap unit="entries">1000</heap><offheap unit="MB">100</offheap></resources></cache>
    </config>
    
    • <heap unit="entries">1000</heap>: 设置堆内存中缓存的最大条目数为 1000。
    • <offheap unit="MB">100</offheap>: 设置堆外内存中缓存的最大大小为 100MB。
  3. 配置 Spring 使用 Ehcache:

    application.ymlapplication.properties 中指定 Ehcache 配置文件的位置。

    application.yml:

    spring:cache:type: ehcacheehcache:config: classpath:ehcache.xml
    

    application.properties:

    spring.cache.type=ehcache
    spring.cache.ehcache.config=classpath:ehcache.xml
    
2.3 使用 Redis 作为缓存实现
  1. 添加依赖:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置 Redis:

    application.ymlapplication.properties 中配置 Redis 连接信息。

    application.yml:

    spring:cache:type: redisredis:host: localhostport: 6379
    

    application.properties:

    spring.cache.type=redis
    spring.redis.host=localhost
    spring.redis.port=6379
    
  3. 可选配置:

    你可以进一步配置 Redis 的缓存行为,例如设置最大内存大小和淘汰策略。

    application.yml:

    spring:redis:lettuce:pool:max-active: 20max-idle: 10min-idle: 5timeout: 5000ms
    

3. 其他相关注解

除了 @Cacheable,Spring 还提供了其他几个注解来管理缓存:

3.1 @CachePut

@CachePut 注解用于更新缓存中的值,但不会影响方法的执行。每次调用带有 @CachePut 注解的方法时,都会执行方法体并将结果存入缓存。

@CachePut(value = "sortedData", key = "#param")
public TableDataInfo updateSortedData(String param) {// 更新逻辑return new TableDataInfo();
}
3.2 @CacheEvict

@CacheEvict 注解用于从缓存中移除一个或多个条目。适用于需要清除缓存的情况。

@CacheEvict(value = "sortedData", key = "#param")
public void deleteSortedData(String param) {// 删除逻辑
}// 清除整个缓存
@CacheEvict(value = "sortedData", allEntries = true)
public void clearAllSortedData() {// 清除所有缓存
}
3.3 @Caching

@Caching 注解允许你在同一个方法上组合多个缓存操作。

@Caching(put = {@CachePut(value = "sortedData", key = "#param"),@CachePut(value = "anotherCache", key = "#param")},evict = {@CacheEvict(value = "oldCache", key = "#param")}
)
public TableDataInfo updateAndEvict(String param) {// 更新逻辑return new TableDataInfo();
}

4. 示例代码

下面是一个完整的示例,展示了如何使用 @Cacheable 注解以及配置 Caffeine 缓存。

4.1 项目结构
src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           ├── Application.java
│   │           ├── config
│   │           │   └── CacheConfig.java
│   │           ├── service
│   │           │   └── DataService.java
│   │           └── model
│   │               └── TableDataInfo.java
│   └── resources
│       └── application.yml
4.2 Application.java
package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
4.3 CacheConfig.java
package com.example.config;import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic CacheManager cacheManager() {CaffeineCacheManager cacheManager = new CaffeineCacheManager("sortedData");cacheManager.setCaffeine(caffeineCacheBuilder());return cacheManager;}Caffeine<Object, Object> caffeineCacheBuilder() {return Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.SECONDS).maximumSize(1000);}
}
4.4 DataService.java
package com.example.service;import com.example.model.TableDataInfo;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;@Service
public class DataService {@Cacheable("sortedData")public TableDataInfo getSortedData(String param) {// 模拟耗时操作try {Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}// 返回模拟数据return new TableDataInfo();}
}
4.5 TableDataInfo.java
package com.example.model;public class TableDataInfo {// 模拟数据模型
}
4.6 application.yml
spring:cache:type: caffeine

5. 注意事项

  1. 缓存一致性:

    • 确保在更新数据时正确使用 @CachePut@CacheEvict 注解,以保持缓存的一致性。
    • 对于分布式系统,考虑使用支持分布式缓存的实现(如 Redis)。
  2. 缓存失效策略:

    • 根据业务需求选择合适的缓存失效策略(如基于时间、基于条件等)。
    • 定期清理过期或不必要的缓存条目,以避免内存泄漏。
  3. 缓存击穿和穿透:

    • 缓存击穿: 当缓存失效后,大量请求同时涌入数据库,导致数据库压力骤增。
      • 解决方案: 可以使用互斥锁(如 Redis 分布式锁)来防止缓存击穿。
    • 缓存穿透: 当查询一个不存在的数据时,所有请求都直接打到数据库。
      • 解决方案: 可以在缓存中存储一个空对象或特殊标记,表示该数据不存在。
  4. 缓存雪崩:

    • 当大量缓存同时失效时,大量请求直接打到数据库,导致数据库压力骤增。
    • 解决方案: 可以设置不同的过期时间,避免缓存同时失效。

6. 调试和监控

为了更好地管理和调试缓存,可以使用以下工具和方法:

  • 日志记录: 在方法上添加日志记录,查看缓存的命中率和缓存操作的频率。
  • 监控工具: 使用监控工具(如 Prometheus、Grafana)来监控缓存的性能指标。
  • Spring Boot Actuator: 提供了缓存相关的端点,可以方便地查看缓存的状态和统计信息。

启用 Spring Boot Actuator:

  1. 添加依赖:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  2. 配置暴露端点:

    application.yml:

    management:endpoints:web:exposure:include: "caches"
    
  3. 访问缓存端点:

    访问 http://localhost:8080/actuator/caches 可以查看缓存的状态信息。

总结

通过使用 @Cacheable 注解,可以轻松地在 Spring 应用中实现缓存机制,从而提高应用的性能和响应速度。结合不同的缓存实现(如 Caffeine、Ehcache、Redis),你可以根据具体需求灵活配置缓存策略,确保缓存的有效性和高效性。

相关文章:

Spring Boot项目@Cacheable注解的使用

Cacheable 是 Spring 框架中用于缓存的注解之一&#xff0c;它可以帮助你轻松地将方法的结果缓存起来&#xff0c;从而提高应用的性能。下面详细介绍如何使用 Cacheable 注解以及相关的配置和注意事项。 1. 基本用法 1.1 添加依赖 首先&#xff0c;确保你的项目中包含了 Spr…...

mac开发环境配置笔记

1. 终端配置 参考&#xff1a; Mac终端配置笔记-CSDN博客 2. 下载JDK 到 oracle官网 下载jdk: oracle官网 :Java Downloads | Oraclemac的芯片为Intel系列下载 x64版本的jdk&#xff1b;为Apple Mx系列使用 Arm64版本&#xff1b;oracle官网下载时报错&#xff1a;400 Bad R…...

重装CentOS YUM

1. 检查是否已安装 YUM 运行以下命令检查 YUM 是否已安装&#xff1a; yum list installed | grep yum 如果输出中包含 yum&#xff0c;则说明 YUM 已安装。 2. 卸载旧版本的 YUM&#xff08;如有必要&#xff09; 如果需要重新安装 YUM&#xff0c;可以先卸载旧版本&…...

对免认证服务提供apikey验证

一些服务不带认证&#xff0c;凡是可以访问到服务端口&#xff0c;都可以正常使用该服务&#xff0c;方便是方便&#xff0c;但是不够安全。 比如ollama默认安装后就是这样。现在据说网上扫一下端口11434&#xff0c;免apikey的ollama服务一大堆。。。 那我们怎样将本机安装的o…...

数据库驱动免费下载(Oracle、Mysql、达梦、Postgresql)

数据库驱动找起来好麻烦&#xff0c;我整理到了一起&#xff0c;需要的朋友免费下载&#xff1a;驱动下载 目前收录了Oracle、Mysql、达梦、Postgresql的数据库驱动的多个版本&#xff0c;后续可能会分享更多。...

OceanBase 初探学习历程之——安装部署

一、介绍 OceanBase 数据库是一个原生的分布式关系数据库&#xff0c;它是完全由阿里巴巴和蚂蚁集团自主研发 的项目。OceanBase 数据库构建在通用服务器集群上&#xff0c;基于 Paxos 协议和分布式架构&#xff0c;提供 金融级高可用和线性伸缩能力&#xff0c;不依赖特定硬件…...

Windows 下免费开源的多格式文件差异对比工具

软件介绍 有这样一款诞生于 2000 年、专为 Windows 系统打造的开源免费工具&#xff0c;截至 2025 年 1 月已更新至 2.16.46 版本&#xff0c;它就是文件与文件夹比较的得力助手。 其支持文本文件、Word、Excel、PPT 网页、图像等多种格式对比&#xff0c;利用高亮显示行内差…...

Vue3+element UI:使用el-dialog时,对话框不出现解决方案

​​​​ 解决方案&#xff1a;在<el-dialog>标签中&#xff0c;添加:append-to-body“true”*&#xff0c;对话框即可弹出。*...

postman调用ollama的api

按照如下设置&#xff0c;不需要设置key 保持长会话的方法 # 首次请求 curl http://localhost:11434/api/generate -d {"model": "deepseek-r1:32b","prompt": "请永久记住&#xff1a;110&#xff0c;1-12&#xff0c;之后所有数学计算必…...

PyTorch的dataloader制作自定义数据集

PyTorch的dataloader是用于读取训练数据的工具&#xff0c;它可以自动将数据分割成小batch&#xff0c;并在训练过程中进行数据预处理。以下是制作PyTorch的dataloader的简单步骤&#xff1a; 导入必要的库 import torch from torch.utils.data import DataLoader, Dataset定…...

如何调用 DeepSeek API:详细教程与示例

目录 一、准备工作 二、DeepSeek API 调用步骤 1. 选择 API 端点 2. 构建 API 请求 3. 发送请求并处理响应 三、Python 示例&#xff1a;调用 DeepSeek API 1. 安装依赖 2. 编写代码 3. 运行代码 四、常见问题及解决方法 1. API 调用返回 401 错误 2. API 调用返回…...

Hadoop-HA集群部署

集群的服务器规划&#xff1a; 配置免密登陆&#xff1a;&#xff08;这里示范的是第一台服务器&#xff0c;其余的操作一样&#xff09;&#xff0c;免密登陆是为了执行脚本统一操作&#xff0c;启动&#xff0c;如&#xff08;hdfs集群&#xff1a;1上启动2.5.6.7&#xff09…...

三、linux字符驱动详解

在上一节完成NFS开发环境的搭建后&#xff0c;本节将探讨Linux字符设备驱动的开发。字符设备驱动作为Linux内核的重要组成部分&#xff0c;主要负责管理与字符设备&#xff08;如串口、键盘等&#xff09;的交互&#xff0c;并为用户空间程序提供统一的读写操作接口。 驱动代码…...

【Research Proposal】基于提示词方法的智能体工具调用研究——研究问题

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;研究问题1. 如何优化提示词方法以提高智能体的工具调用能力&#xff1f;2. 如何解决提示词方法在多模态任务中的挑战&#xff1f;3. 如何通过提示词优化智能体…...

【从0做项目】Java文档搜索引擎(9)烧脑终章!

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 文章导读 零&#xff1a;项目结果展示 一&#xff1a;导入 二&#xff1a;问题引入 1&#xff1a;情…...

python: SQLAlchemy (ORM) Simple example using mysql in Ubuntu 24.04

mysql sql script: create table School 表 (SchoolId char(5) NOT NULL comment主鍵primary key&#xff0c;學校編號,SchoolName nvarchar(500) NOT NULL DEFAULT comment 學校名稱,SchoolTelNo varchar(8) NULL DEFAULT comment電話號碼,PRIMARY KEY (SchoolId) #主…...

如何为自己的 PDF 文件添加密码?在线加密 PDF 文件其实更简单

随着信息泄露和数据安全问题的日益突出&#xff0c;保护敏感信息变得尤为重要。加密 PDF 文件是一种有效的手段&#xff0c;可以确保只有授权用户才能访问或修改文档内容。本文将详细介绍如何使用 CleverPDF 在线工具为你的 PDF 文件添加密码保护&#xff0c;确保其安全性。 为…...

echarts 折线图动态基准线设置超出基准线标红

基准线属性&#xff1a;markLine 线条标红关键属性&#xff1a;visualMap 小于&#xff1a; lt (less than) 大于&#xff1a;gt (greater than) 小于等于&#xff1a;lte (Less than or equal to) 大于等于&#xff1a;gte (Greater than or equal to) 1、基础应用——2条基准…...

Part 3 第十二章 单元测试 Unit Testing

概述 第十二章围绕单元测试展开&#xff0c;阐述了单元测试的实践与重要性&#xff0c;通过对比其他测试类型&#xff0c;突出其特点&#xff0c;还介绍了单元测试的最佳实践、避免的反模式以及与测试替身相关的内容&#xff0c;为编写高质量单元测试提供指导。 章节概要 1…...

C++与Python:两种编程语言的区别

C和Python都是当今编程领域广泛使用的语言&#xff0c;它们各有特色&#xff0c;适用于不同的开发场景。本文将从语言特性、性能、学习难度、应用领域等多个方面探讨C与Python之间的区别。 一、语言特性 类型系统&#xff1a; C&#xff1a;是一种静态类型语言&#xf…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...