SpringBoot2.x系列教程31--SpringBoot中的缓存实现方案介绍

news2025/7/7 23:38:36

前言

作为一个程序员,我们不仅仅要把项目的功能实现出来,还要追求这个功能的高效和健壮,我们得想办法对项目的功能进行各种优化和性能的提升。其中缓存就是对程序性能进行显著提升的一个有效手段,那么在SpringBoot中对缓存有哪些支持方案呢?

今天 壹哥 就给大家讲一下SpringBoot中支持的几种缓存实现方案,本文会重点讲解Spring Cache这种缓存方案。

一. Spring中对缓存的支持

1. Spring Cache简介

从Spring 3.1开始,Spring中就引入了对Cache的支持,而在Spring Boot中我们可以通过添加spring-boot-starter-cache的缓存依赖,实现缓存功能。

Spring中是通过依赖org.springframework.cache.Cacheorg.springframework.cache.CacheManager接口来实现缓存的,我们在Spring Boot中只要通过@EnableCaching注解开启缓存支持,Spring Boot就会根据实现自动配置一个合适的CacheManager。

2. Spring Boot支持的缓存提供商

Spring Boot中支持的缓存提供商的默认顺序如下:

  • Generic
  • JCache(JSR-107)(EhCache 3, Hazelcast, Infinispan)
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine
  • Guava
  • Simple

Spring Boot 为我们提供了多种缓存CacheManager配置方案,默认情况下会使用基于内存map的缓存方案ConcurrenMapCacheManager,内部默认是利用ConcurrentHashMap的来实现缓存。

我们可以通过‘spring.cache.type’属性来强制指定到底使用哪种缓存提供商,如果需要在一些环境(比如,测试)中禁用全部缓存也可以使用该属性。

3. Spring Cache原理

Spring Cache是作用在方法上的,其核心实现逻辑如下:

当我们在调用一个缓存方法时,会把该方法参数和返回结果作为一个键值对存放在缓存中;
等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。
所以在使用Spring Cache的时候,我们要确保缓存的方法的幂等性,也就是对于相同的方法参数要有相同的返回结果。
复制代码

4. Spring Cache的实现方案

Spring对Cache的实现方案有2种方式。

  • 基于注解配置方式;
  • 基于XML配置方式。

其中基于注解(annotation)的缓存(cache)技术是在Spring 3.1 引入的,它本质上不是一个具体的缓存实现方案(例如 EHCache),而是一个对缓存使用的抽象,通过在已有代码中添加少量关于缓存的注解annotation,就能够达到缓存的效果。

二. Spring Cache注解实现方案详解

1. Spring Cache中常用缓存注解

在Spring Cache中,为我们提供了如下几个常用的缓存相关注解,希望各位可以记住:

  • @Cacheable****
  • @CachePut****
  • @CacheEvict****
  • @Caching****

2. 注解实现方案的特点

  • 通过少量的配置 annotation 注解即可使得已有代码支持缓存;
  • 支持 SpEL 表达式,能使用对象的任何属性或者方法来定义缓存的 key 和 condition;
  • 支持 AspectJ,并通过其实现任何方法的缓存支持;
  • 支持自定义 key 和缓存管理器,具有相当的灵活性和扩展性;
  • 提供开箱即用的缓存临时存储方案;
  • 支持和主流的专业缓存方案(例如Redis)集成。

接下来我会分别对这几个注解进行详细的介绍。

三. @Cacheable注解

1. 注解作用

可以作用在方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。

2. 用法举例

//单缓存名称:
@Cacheable(value=”cache1”)
    
//多缓存名称:
@Cacheable(value={”cache1”,”cache2”}
复制代码

3. 参数介绍

value参数是必须指定的,表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

3.1 value:缓存的名称

每一个缓存名称代表一个缓存对象。当一个方法填写多个缓存名称时将创建多个缓存对象。
当多个方法使用同一缓存名称时相同参数的缓存会被覆盖。
所以通常情况我们使用“包名+类名+方法名”或者使用接口的RequestMapping作为缓存名称防止命名重复引起的问题。
复制代码

3.2 key:缓存的 key

key标记了缓存对象中的每一个缓存数据,当我们没有指定该属性时,Spring将使用默认策略生成key,系统会自动按照方法的所有入参生成key,也就是说相同的入参值将会返回同样的缓存结果。

我们也可以利用自定义策略,通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。

4. 示例代码

如下列无论方法存在多少个入参,只要userName值一致,则会返回相同的缓存结果。

/**
* key 是指传入时的参数
*/
@Cacheable(value="users", key="#id")
public User find(Integer id) {
    return null;
}
   
// 表示第一个参数
@Cacheable(value="users", key="#p0")
public User find(Integer id) {
    return null;
}
   
// 表示User中的id值
@Cacheable(value="users", key="#user.id")
public User find(User user) {
    return null;
}

// 表示第一个参数里的id属性值
@Cacheable(value="users", key="#p0.id")
public User find(User user) {
    return null;
}
复制代码

除了上述使用方法的参数作为key之外,Spring还为我们提供了一个root对象用来生成key。

当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:

// key值为: user中的name属性的值
@Cacheable(value={"users", "xxx"}, key="caches[1].name")
public User find(User user) {
    return null;
}
复制代码

5. condition缓存的条件

有时候我们可能并不希望缓存一个方法的所有返回结果,这时可以通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。满足条件后,方法的结果才会被缓存,不填写则认为全部无条件缓存。

使用 SpEL表达式编写条件,返回 true 或者 false,只有为 true 才进行缓存。

//只有用户名长度大于2时参会进行缓存。
@Cacheable(value=”cache1”,condition=”#userName.length()>2”)
复制代码

四. @CachePut注解

1. 注解作用

主要针对方法配置,能够根据方法的请求参数对其结果进行缓存。和 @Cacheable 不同的是,它每次都会触发真实方法的调用,此注解常被用于更新缓存使用。

2. 参数介绍

2.1 value:缓存的名称

@CachePut(value=”cache1”)
@CachePut(value={”cache1”,”cache2”}
复制代码

2.2 key:缓存的 key

@CachePut(value=”cache1”,key=”#userName”)
复制代码

2.3 condition:缓存的条件

@CachePut(value=”cache1”,condition=”#userName.length()>2”)
复制代码

五. @CacheEvict注解

1. 注解作用

作用在方法上,根据一定的条件对缓存结果进行清空。

2. 参数介绍

2.1 value 缓存的名称

删除指定名称的缓存对象,必须与下面的其中一个参数配合使用:

//例如:
@CacheEvict(value=”cache1”) 

//或者
@CacheEvict(value={”cache1”,”cache2”}
复制代码

2.2 key 缓存的 key

删除指定key的缓存对象。

@CacheEvict(value=”cache1”,key=”#userName”)
复制代码

2.3 condition:缓存的条件

删除指定条件的缓存对象。

@CacheEvict(value=”cache1”,condition=”#userName.length()>2”)
复制代码

2.4 allEntries属性

allEntries方法执行后清空所有的缓存;默认为 false,如果指定为 true,则方法调用后将立即清空所有缓存。

//例如:
@CacheEvict(value=”cache1”,allEntries=true)
复制代码

2.5 beforeInvocation属性

beforeInvocation 方法执行前清空所有缓存。默认为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存。默认情况下,如果方法执行抛出异常,则不会清空缓存。

//例如:
@CacheEvict(value=”cache1”,beforeInvocation=true)
复制代码

六. @Caching注解

@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。

@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),@CacheEvict(value = "cache3", allEntries = true) })
public User find(Integer id) {
    return null;
}
复制代码

结语

至此,壹哥 就给大家介绍了Spring Cache这种缓存实现方案,尤其是该缓存中提供的几个重要缓存注解,在下一章节中,我将会带大家通过代码实现缓存功能。

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

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

相关文章

我的数学学习回忆录——一个数学爱好者的反思(一)

早点关注我,精彩不迷路!我是一个热爱数学20余年的数学爱好者,曾奉数学为宇宙的真理和一切行动的指南的极客。从小对数字世界好奇和敏感,玩各种数学思维游戏,然后在高考应试和竞赛中扎实训练数学基础,逐渐把…

[附源码]java毕业设计中华美食网站

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

docker安装filebeat 进行日志收集

1.介绍 filebeat和beats的关系 首先filebeat是Beats中的一员。   Beats在是一个轻量级日志采集器,其实Beats家族有6个成员,早期的ELK架构中使用Logstash收集、解析日志,但是Logstash对内存、cpu、io等资源消耗比较高。相比Logstash&#x…

matlab学习笔记(五)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 matlab学习笔记(五)一、绘制下列连续时间信号的波形图二、绘制下列离散时间信号的波形图三.已知信号f(t)的波形如下图所示,请用MATLAB绘出…

ES filter查询 高亮查询 聚合查询

filter查询 query,根据你的查询条件,去计算文档的匹配度得到一个分数,并且根据分数进行排序,不会做缓存的。 filter,根据你的查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进…

C++中的多态(上)

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸 文章目录一、多态的概念二、虚函数三、破坏多态条件的现象1.破坏多态条件一,虚函数重写/覆盖2.破坏多态条件二四、 多态的两个条件不满足…

数据库审核工具SQLE部署及使用

点击上方蓝字关注我SQLE( https://opensource.actionsky.com/sqle/ )是由上海爱可生信息技术股份有限公司 开发并开源,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。我们…

PC_磁盘HDD_SSD

文章目录磁盘存储器组成磁盘驱动器磁盘控制器盘片platter存储区域磁盘结构磁道track扇区sector🎈/块Block🎆磁头(Head)圆柱面cylinder磁记录原理磁盘性能指标记录密度磁盘的容量非格式化容量格式化容量数据传输率磁盘转速旋转周期T例平均存取时间纯读/写…

网络与通信程序设计-基于UDP的广播通信实例

目录 实验内容和设计思想 实验的内容 UDP的设计思想 UDP的协议头部 UDP通信编程思想 UDP的工作流程 UDP编程收发函数 广播通信 广播模式设置 广播套接字 UDP Socket的使用过程 UDP广播通信实例实现 initsock.h 服务器发送广播消息 客户端接收广播消息 运行效果 …

HttpMessageConverter 消息转换器

HttpMessageConverter 简介 HttpMessageConverter 是SpringMVC中提供的一个策略接口,它是一个消息转换器类,Spring Mvc中就是由HttpMessageConverter负责转换HTTP的请求和响应。 默认情况下,Spring Boot 会自动加载如下消息类型转换器&…

spring复习01,IOC的思想和第一个spring程序helloWorld

spring复习01,IOC的思想及本质IOC的思想一个小例子,来体会IOC的基础思想。dao层dao层接口dao层实现类service层service层接口service层实现类测试代码service层实现类修改测试代码修改IOC容器在spring中的简单实现创建项目在pom.xml中引入依赖实体类创建…

C# 拨号面板 高亮显示

一 拨号面板 显示:绘制4x3; 数据:每一格对应一个数字; 行为:点击单元格时有反应; 二 拨号事件 当点击某个号码时,触发拨号事件。 设计思路: ① 重写OnMouseClick(); ② 根据鼠标点击位置&am…

JVET-AB0117-基于模板的帧内推导的方向性融合

本提案是针对 ECM 中的 TIMD(基于模板的帧内模式推导,Template based intra mode derivation ) 的技术的加权方式的改进。具体地,本提案提出使用方向混合(directional blending)来加权TIMD使用模板推导的两…

SpringBoot SpringBoot 原理篇 1 自动配置 1.13 bean 依赖属性配置

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.13 bean 依赖属性配置1.13.1 环境准备1.13.2 bean 依赖属性配置1…

【软件测试】作为测试人,因工作与开发吵了一架碰撞,该咋办......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 测试与开发在工作中…

【网页设计】HTML+CSS保护野生动物北极熊介绍网页设计专题

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

傻白入门芯片设计,RDL/Interposer/EMIB/TSV(五)

一、再分配层(RDL) 主要原理就是在晶片表面沉积金属层和介电层。它形成了一个再分配层,以携带相应的金属布线模式,并在芯片外的松散区域上重新排列芯片的IO端口。由于RDL形成的金属布线的线宽和间距较小,从而提供了更…

MySQL之InnoDB架构浅析

InnoDB是一个兼顾高可靠性和高性能的通用存储引擎。在 MySQL 5.7 中,InnoDB是默认的 MySQL 存储引擎。 InnoDB 的主要优势 支持事物,具备crash-safe的能力支持行锁以及MVCC,具备良好的多用户并发性和性能Buffer Pool,提升热点数…

第8章 综合案例—构建DVD租赁商店数据仓库

目录 章节概要 案例背景介绍 数据仓库的架构模型 数据仓库的架构模型 数据库sakila的下载和安装 数据库sakila简介 数据库sakila中 数据表之间的关系 数据表简介 用于储存电影基本信息及相关介绍的数据,该数据表各个字段的含义如表。 用于储存定义电影id所…

Python爬虫

前言 这个故事,从头讲起。 2022 年上班第一天,我们做了一个重要决定,就是打造精品学习路线,为初学者指明前进的方向,以及常见的避坑技巧。 (文末送读者福利) 我承认这是一件非常有挑战的事情…