spring框架中的本地缓存:spring cache基本使用

基本概念及原理

处理逻辑

Spring Cache 是 Spring 提供的一整套的缓存解决方案

虽然它本身并没有提供缓存的实现,但是它提供了一整套的接口和代码规范、配置、注解等,这样它就可以整合各种缓存方案了

处理逻辑:每次调用某方法,而此方法又是带有缓存功能时,Spring 框架就会检查指定参数的那个方法是否已经被调用过,如果之前调用过,就从缓存中取之前调用的结果;如果没有调用过,则再调用一次这个方法,并缓存结果,然后再返回结果,那下次调用这个方法时,就可以直接从缓存中获取结果了

实现步骤

SpringCache实现步骤 :

  1. 启用缓存 :通过 @EnableCaching 注解触发 Spring 的缓存代理配置
  2. AOP 拦截 :Spring 为标记注解的方法生成代理对象,在方法调用前后插入缓存操作。
  3. 缓存处理 :根据注解配置,调用 CacheManager 获取 Cache 实例,执行读写或删除操作。

核心原理

Spring Cache 的核心原理基于 AOP(面向切面编程) 和 缓存抽象 ,通过注解简化缓存逻辑的集成。

核心是 缓存抽象层 和 动态代理机制 ,结合 Spring Boot 的自动配置,可快速集成多种缓存方案,显著提升系统性能

Spring Cache 通过 抽象层 解耦具体缓存技术

  • 适配器模式 :通过 CacheManager 和 Cache 接口适配不同缓存实现(如 Redis、Ehcache)。
  • 自动配置 :Spring Boot 的 spring-boot-autoconfigure 模块自动检测并配置缓存实现(如引入 spring-boot-starter-data-redis 后自动启用 Redis 缓存)。

核心组件与抽象

Cache 接口 :定义缓存操作(如 get、put、evict),具体实现由第三方缓存技术(如 Redis、Caffeine)提供。

CacheManager 接口 :管理多个 Cache 实例,负责创建、配置和获取缓存对象

例如:

  • ConcurrentMapCacheManager(默认内存缓存)
  • RedisCacheManager(Redis 实现)
  • EhCacheCacheManager(Ehcache 实现)

核心注解

Spring 提供了五个注解来声明缓存规则。

  • @Cacheable:方法执行前检查缓存,命中则直接返回,否则执行方法并缓存结果
  • @CachePut:方法调用前不会去缓存中查找,无论缓存是否存在,都执行方法并更新缓存
  • @CacheEvict:删除指定缓存,清除缓存中的一条或多条记录
  • @Caching:组合多个缓存操作
  • @CacheConfig:在类级别共享相同的缓存的配置
注解作用常用参数
@Cacheable方法结果缓存(先查缓存,未命中执行方法),一般用在查询方法上value, key, condition
@CachePut强制更新缓存(始终执行方法),一般用在新增方法上value, key, unless
@CacheEvict清除缓存,一般用在更新或者删除方法上value, key, allEntries
@Caching组合多个缓存操作,实现同一个方法上同时使用多种注解cacheable, put, evict
@CacheConfig类级别共享缓存配置cacheNames, keyGenerator

SpEL 表达式

场景表达式示例
防缓存穿透unless = “#result == null”
多字段复合键key = “#user.id + ‘:’ + #user.deviceId”
时间戳动态键key = “T(System).currentTimeMillis()”
权限过滤condition = “#authLevel > 3”
集合非空判断condition = “!#list.isEmpty()”

还有许多其他的表达式,待使用时再去专门查询吧

实现

pom依赖

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

选择使用的缓存

# 使用redis进行缓存
spring.cache.type=redis

Spring Cache 支持很多缓存中间件作为框架中的缓存,总共有 9 种选择:

  • caffeine:Caffeine 是一种高性能的缓存库,基于 Google Guava。
  • couchbase:CouchBase是一款非关系型JSON文档数据库。
  • generic:由泛型机制和 static 组合实现的泛型缓存机制。
  • hazelcast:一个高度可扩展的数据分发和集群平台,可用于实现分布式数据存储、数据缓存。
  • infinispan:分布式的集群缓存系统。
  • jcache:JCache 作为缓存。它是 JSR107 规范中提到的缓存规范。
  • none:没有缓存。
  • redis:用 Redis 作为缓存
  • simple:用内存作为缓存

测试缓存

基本概念

启动类上面添加@EnableCaching注解

指定某方法开启缓存功能。在方法上添加 @Cacheable 缓存注解就可以了

@Cacheable 注解中,可以添加四种参数:value,key,condition,unless

  • value:指定缓存名称(必填)
  • key:自定义缓存键(SpEL表达式)
  • condition:执行前条件判断(SpEL)
  • unless:执行后结果过滤(SpEL)
参数类型作用示例
valueString[]指定缓存名称(必填)value = “users” 或 value = {“cache1”, “cache2”}
keyString自定义缓存键(SpEL表达式)key = "#userId"或key = “T(java.util.UUID).randomUUID().toString()”
conditionString执行前条件判断(SpEL)condition = "#userId > 1000"或condition = “#name.startsWith(‘admin’)”
unlessString执行后结果过滤(SpEL)unless = "#result == null"或unless = “#result.age < 18”

使用示例1

第一次调用下面这个接口前,缓存里面是没有hot缓存,也没有这个test方法的结果缓存

调用test方法后,缓存中便会创建出hot这个缓存,其中缓存了一个key(默认值SimpleKey[]),其中有一个值

  • 缓存中 key 对应的 value 默认使用 JDK 序列化后的数据。
  • value 的过期时间为 -1,表示永不过期。

key:hot:SimpleKey[]
value:222

@RequestMapping("/test2")
@Cacheable({"hot"})
public int test() {return 222;
}

第二次调用test()方法时,便会直接读缓存,而不去执行test里面的方法

@RequestMapping("/test2")
@Cacheable({"hot"})
public int test2() {return 456;
}

如果再将类名改为test2后,缓存获取到的值还是test方法时缓存的值222,因为两个方法的key值都是SimpleKey[]

使用示例2

// 启用缓存(配置类)
@EnableCaching
@Configuration
public class CacheConfig {@Beanpublic CacheManager cacheManager() {return new ConcurrentMapCacheManager("users"); // 内存缓存}
}// 业务层使用
@Service
public class UserService {// 缓存读取(value=缓存名称,key=缓存键)@Cacheable(value = "users", key = "#userId")public User getUserById(Long userId) {// 实际数据库查询return userRepository.findById(userId);}// 缓存更新@CachePut(value = "users", key = "#user.id")public User updateUser(User user) {return userRepository.save(user);}// 缓存清除@CacheEvict(value = "users", key = "#userId")public void deleteUser(Long userId) {userRepository.deleteById(userId);}
}

自定义配置类

自定义缓存过去时间等

# 使用 Redis 作为缓存组件
spring.cache.type=redis
# 缓存过期时间为 3600s
spring.cache.redis.time-to-live=3600000
# 缓存的键的名字前缀
spring.cache.redis.key-prefix=passjava_
# 是否使用缓存前缀
spring.cache.redis.use-key-prefix=true
# 是否缓存控制,防止缓存穿透
spring.cache.redis.cache-null-values=true

自定义 key

在 @Cacheable 注解里面加上 key 的值 #root.method.name。这是一种特有的表达式,称作 SpEL 表达式,这里代表用方法名作为缓存 key 的名字

@Cacheable(value = {"hot"}, key = "#root.method.name")

如果按上述去配置的话,缓存的key的名称便是这个方法名

自定义条件

可以自定义条件来决定是否将缓存功能关闭。这里就要用到@Cacheable 另外两个属性:condition 和 unless,它俩的格式还是用 SpEL 表达式

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

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

相关文章

AI大模型学习二十四、实践QEMU-KVM 虚拟化:ubuntu server 25.04 下云镜像创建Ubuntu 虚拟机

一、说明 虽然说大部分的场合&#xff0c;docker都能解决问题&#xff0c;但是有些大型的软件安装时如果修改配置会很麻烦&#xff0c;比方说前面遇到的code-server和dify 默认都是80和443端口要使用&#xff0c;安装在一起就会端口冲突&#xff0c;通过该端口来解决问题&#…

安卓中0dp和match_parent区别

安卓中的 0dp 和 match_parent 的区别&#xff1f; 第一章 前言 有段时间&#xff0c;看到同事在编写代码的时候&#xff0c;写到的是 0dp 有时候自己写代码的时候&#xff0c;编写的是 match_parent 发现有时候效果很类似。 后来通过一个需求案例&#xff0c;才发现两者有着…

二十、案例特训专题3【系统设计篇】web架构设计

一、前言 二、内容提要 三、单机到应用与数据分离 四、集群与负载均衡 五、集群与有状态无状态服务 六、ORM 七、数据库读写分离 八、数据库缓存Memcache与Redis 九、Redis数据分片 哈希分片如果新增分片会很麻烦&#xff0c;需要把之前数据取出来再哈希除模 一致性哈希分片是…

基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(一)

前置说明 开发语言&#xff1a;Rust Web框架&#xff1a;Rocket 数据库&#xff1a;PostgreSQL 开发步骤 新建项目&#xff1a; cargo new projectname 在Cargo.toml文件里配置如下依赖&#xff1a; [dependencies] rocket {version"0.5.0",features["json&qu…

中国城市间交通驾车距离矩阵(2024)

中国城市间交通驾车距离矩阵(2024) 1852 数据简介 中国城市中心的交通驾车距离&#xff0c;该数据为通过审图号GS(2024)0650的中国城市地图得其城市中心距离&#xff0c;再通过高德地图api计算得出其交通驾车最短距离矩阵&#xff0c;单位为KM&#xff0c;方便大家研究使用。…

MySQL替换瀚高数据库报错: TO_DAYS()不存在(APP)

文章目录 环境症状问题原因解决方案报错编码 环境 系统平台&#xff1a;中标麒麟&#xff08;海光&#xff09;7,中标麒麟&#xff08;飞腾&#xff09;7 版本&#xff1a;4.5 症状 MySQL替换为瀚高数据库进行应用系统适配报错&#xff1a;TO_DAYS&#xff08;&#xff09;不…

驱动-Linux定时-timer_list

了解内核定时相关基础知识 文章目录 简要介绍timer_list 特点API 函数实验测试程序 - timer_mod.c编译文件-Makefile实验验证 注意事项总结 简要介绍 硬件为内核提供了一个系统定时器来计算流逝的时间&#xff08;即基于未来时间点的计时方式&#xff0c; 以当前时刻为计时开始…

计算机网络概要

⽹络相关基础知识 协议 两设备之间使⽤光电信号传输信息数据 要想传递不同信息 那么⼆者ᳵ就需要约定好的数据格式 层 封装 继承 多态是计算机的性质 它们⽀持了软硬件分层的实现 同层协议可以ᳵ接通信 同层协议ᳵ不直接通信 是各⾃调⽤下层提供的结构能⼒完成通信 分层…

QT 使用QPdfWriter和QPainter绘制PDF文件

QT如何生产pdf文件&#xff0c;网上有许多文章介绍&#xff0c;我也是看了网上的文章&#xff0c;看他们的代码&#xff0c;自己琢磨琢磨&#xff0c;才有了本编博客&#xff1b; 其他什么就不详细说了&#xff0c;本篇博客介绍的QPdfWriter和QPainter绘制PDF文件&#xff1b;…

企业标准信息公共服务平台已开放标准通编辑器访问入口

标准通 数字化标准编辑器 专业、高效、便捷 企业标准信息公共服务平台 近日&#xff0c;企业标准信息公共服务平台已开放标准通编辑器访问入口&#xff0c;可进入官网指定版块使用&#xff01; 核心功能亮点 解决企业痛点 传统标准编制&#xff0c;需反复核对格式、逐条…

【Hadoop】--HA高可用搭建--3.2.2

修改环境配置文件 hadoop-env.sh # 在文件末尾添加以下内容&#xff1a; # java_home记得修改 export JAVA_HOME/usr/java/jdk1.8.0xxxx export HDFS_NAMENODE_USERroot export HDFS_DATANODE_USERroot export HDFS_ZKFC_USERroot export HDFS_JOURNALNODE_USERroot export YA…

【skywalking】index“:“skywalking_metrics-all“},“status“:404}

skywalking 启动报错 java.lang.RuntimeException: {"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index [skywalking_metrics-all]","resource.t ype":"inde…

【Android】从垂直同步到屏幕刷新机制(一)

【Android】从垂直同步到屏幕刷新机制 本文参考以及部分图片来源&#xff1a; 垂直同步_小科普&#xff1a;“垂直同步”究竟是什么&#xff1f;-CSDN博客 “终于懂了” 系列&#xff1a;Android屏幕刷新机制—VSync、Choreographer 全面理解&#xff01;-腾讯云开发者社区-腾讯…

ACL完全解析:从权限管理到网络安全的核心防线

访问控制列表&#xff08;ACL&#xff09;是一种用于管理资源访问权限的核心安全机制&#xff0c;广泛应用于操作系统和网络设备中。以下是对ACL的详细解析&#xff1a; 1. 基本概念 定义&#xff1a;ACL是由多个访问控制条目&#xff08;ACE&#xff09;组成的列表&#xff0…

代码审计-php框架开发,实战tp项目,打击微交易,源码获取,扩大战果

实战&#xff0c;不安全写法引发的注入 这个bc靶场源码没有&#xff0c;看老师演示 打开很明显的tp框架源码 拿到tp框架之后第一步&#xff0c;搜索版本信息5.0.5 两个思路 1.代码的不安全写法 2.版本自身存在的漏洞 全局搜索where看看也没有不安全的 哎&#xff1f;&…

大模型的实践应用43-基于Qwen3(32B)+LangChain框架+MCP+RAG+传统算法的旅游行程规划系统

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用43-基于Qwen3(32B)+LangChain框架+MCP+RAG+传统算法的旅游行程规划系统。本报告将阐述基于大模型Qwen3(32B)、LangChain框架、MCP协议、RAG技术以及传统算法构建的智能旅游行程规划系统。该系统通过整合多种技术优势,实…

Jsoup库和Apache HttpClient库有什么区别?

Jsoup 和 Apache HttpClient 是两个功能不同的库&#xff0c;它们在 Java 开发中被广泛使用&#xff0c;但用途和功能有明显的区别&#xff1a; Jsoup 用途&#xff1a;Jsoup 是一个用于解析 HTML 文档的库。它提供了非常方便的方法来抓取和解析网页内容&#xff0c;提取和操作…

腾讯云存储原理

我们来详细展开你提到的两个核心结构概念&#xff1a; 一、“基于分布式文件系统 对象存储技术” 是什么&#xff1f; 1. 分布式文件系统&#xff08;DFS&#xff09;基础 分布式文件系统是一种支持将数据分布在多个存储节点上、并对上层用户透明的文件系统。腾讯云COS虽然是…

python fastapi + react, 写一个图片 app

1. 起因&#xff0c; 目的: 上厕所的时候&#xff0c;想用手机查看电脑上的图片&#xff0c;但是又不想点击下载。此app 应运而生。 2. 先看效果 单击图片&#xff0c;能放大图片 3. 过程: 过程很枯燥。有时候&#xff0c; 有一堆新的想法。 但是做起来太麻烦&#xff0c;…

Kubernetes控制平面组件:Kubelet详解(五):切换docker运行时为containerd

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…