Spring Cache基本使用

Spring 从 3.1 版本开始定义缓存抽象来统一不同的缓存技术;在应用层面与后端存储之间,提供了一层抽象,这层抽象目的在于封装各种可插拔的后端存储( ehcache, redis, guava),最小化因为缓存给现有业务代码带来的侵入。

一、Spring Cache简介

Spring Cache 是 Spring 框架提供的一个缓存抽象,实现了基于注解的缓存功能,它能够轻松地集成到 Spring 应用程序中,为方法调用的结果提供缓存支持,从而提高应用程序的性能和响应速度。

Spring Cache 提供了一种声明式的缓存机制,可以在方法上使用注解来指定需要进行缓存的方法,而无需编写繁琐的缓存代码。

Spring Cache 基本介绍:

  • 声明式缓存支持:Spring Cache 提供了一种声明式的缓存机制,通过在方法上使用注解来声明需要进行缓存的方法。比如:@Cacheable、@CachePut、@CacheEvict等注解。
  • 灵活的缓存策略:Spring Cache 提供了多种灵活的缓存策略,可以根据具体需求选择合适的缓存方案。比如:基于内存缓存、基于 Redis、Ehcache 等第三方缓存框架的集成。
  • 支持缓存管理器:Spring Cache 支持多种缓存管理器,可以根据需要选择适合的缓存管理器。比如:ConcurrentMapCacheManager、EhCacheCacheManager、RedisCacheManager 等。
  • 适用于各种应用场景:Spring Cache 适用于各种应用场景,可以用于缓存方法的返回值、类级别的缓存、缓存的条件判断等。

Spring Cache核心抽象主要体现在两个接口上:

  • org.springframework.cache.cache接口:cache代表缓存组件规范定义(缓存本身),包含缓存的各种操作集合。比如:增加、删除、读取等。
  • org.springframework.cache.cachemanager接口:CacheManager 是 Spring 各种缓存的抽象接口。抽象的意义在于屏蔽实现细节的差异和提供扩展性,这一层cache的抽象解耦了缓存的使用和缓存的后端存储,这样后续可以方便的更换后端存储。

Spring提供了 Cache接口下各种 XxxCache实现。比如:RedisCache, EhCacheCache, ConcurrentMapCache, JCacheCache等。

Spring支持的常用 CacheManager 如下:

Spring Cache 默认使用 ConcurrentMapCacheManager 作为缓存管理器。

在这里插入图片描述
通过使用 Spring Cache,可以轻松地为应用程序中的方法调用提供缓存支持,从而提高应用程序的性能和响应速度,减少对数据库或其他资源的频繁访问。

每次调用需要缓存功能的方法时,Spring 会检查检查指定参数的指定的目标方法是否已经被调用过。

  • 如果有就直接从缓存中获取方法调用后的结果。
  • 如果没有就调用方法并缓 存结果后返回给用户。下次调用直接从缓存中获取。

二、Spring Cache使用

Spring Cache依赖如下:

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

在spring boot项目中,无需添加 Spring Cache 的依赖,因为 Spring Boot 已经自动集成了 Spring Cache。

1、接入Redis使用Spring Cache

添加 Redis依赖:

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

项目配置文件(application.yml)中添加 Redis配置信息:

spring:## Redis 配置信息redis:host: 127.0.0.1port: 6379password: xxxxxxdatabase: 1

1.1 Redis配置类

Redis默认使用 JdkSerializationRedisSerializer序列化器。

  • RedisTemplate 中,k和v默认的序列化方案是 JdkSerializationRedisSerializer 。
  • RedisTemplate<String, Object> 中,k和v默认的序列化方案是 JdkSerializationRedisSerializer 。
  • StringRedisTemplate 中,k和v默认的序列化方案是 StringRedisSerializer 。默认情况下,前面不会有前缀。
@Configuration
public class RedisConfiguration {@Primary@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.java());redisTemplate.setHashValueSerializer(RedisSerializer.java());redisTemplate.setConnectionFactory(factory);// 调用 afterPropertiesSet()方法执行初始化操作redisTemplate.afterPropertiesSet();return redisTemplate;}
}

1.2 Spring Cache配置类

@EnableCaching注解:开启缓存功能,一般放在启动类或者配置类上。

CacheManager可以不用注入,Spring框架会自动注入的。如果我们手动注入,会使用我们自己注入的(适合自定义相关配置信息)。

下面使用 RedisCacheManager作为缓存缓存管理。

@EnableCaching
@Configuration
public class CacheConfiguration {@Beanpublic CacheManager cacheManager(RedisConnectionFactory connectionFactory) {RedisCacheManager cacheManager = RedisCacheManager.create(connectionFactory);return cacheManager;}
}

2、核心注解使用

Spring Cache提供了下面几个核心注解完成缓存功能的实现。

  • @EnableCaching:开启缓存功能
  • @Cacheable:定义缓存,用于触发缓存
  • @CachePut:定义更新缓存,触发缓存更新
  • @CacheEvict:定义清除缓存,触发缓存清除
  • @Caching:组合定义多种缓存功能
  • @CacheConfig:定义公共设置,位于class之上

2.1 @Cacheable注解

@Cacheable注解:定义缓存数据或者获取缓存数据操作。
@Cacheable 注解可以应用于类或方法上。当应用于类上时,表示该类的所有方法的返回值都可以被缓存;当应用于方法上时,表示特定方法的返回值可以被缓存。

该注解标注的方法每次被调用前都会触发缓存校验,校验指定参数的缓存是否已存在(已发生过相同参数的调用),若存在,直接返回缓存结果,否则执行方法内容,最后将方法执行结果保存到缓存中。

2.1.1 主要属性

主要属性如下:

  • value:必填,指定缓存数据存放在哪块命名空间(缓存名)。用于指定要操作的缓存名称或缓存管理器的名称。可以是一个字符串,也可以是一个字符串数组,用于指定多个缓存名称。
  • cacheNames:与 value 差不多,二选一即可。
  • key:可选,指定缓存条目的键,用于唯一标识缓存中的条目。SpEL 表达式可以用于动态地生成键值。如果不指定 key,Spring Cache 将会使用默认的键生成策略来生成键值。
  • condition:条件符合则缓存。指定一个 SpEL 表达式,用于判断是否执行缓存操作。只有当表达式的值为 true 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • unless:条件符合则不缓存。指定一个 SpEL 表达式,用于判断是否不执行缓存操作。只有当表达式的值为 false 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • keyGenerator:指定一个自定义的键生成器,用于生成缓存条目的键值。默认为空,表示使用默认的键生成策略。key/keyGenerator二选一使用。
  • cacheManager:指定一个自定义的缓存管理器,用于指定缓存的实现。默认为空,表示使用默认的缓存管理器。
  • cacheResolver:指定一个自定义的缓存解析器,用于解析缓存的实现。默认为空,表示使用默认的缓存解析器。
  • sync:指定是否启用同步模式。如果设置为 true,那么缓存操作将在调用方法的同一线程中执行,否则将在后台线程中异步执行。默认为 false。
2.1.2 使用
    @Cacheable(value = "userCache_", key = "#id", unless = "#result==null")@Overridepublic UserDTO getById(Long id) {if (id == null || id <= 0L) {return null;}UserDO userDO = userMapper.selectById(id);return do2DTO(userDO);}

unless参数里的 #result为方法的返回值。所以,判断方法返回值为 null 时,则不缓存。

在这里插入图片描述

2.2 @CachePut注解

@CachePut注解:更新缓存数据操作。
@CachePut与 @Cacheable 不同,@CachePut 不会检查缓存中是否已经存在相同键的条目,而是直接将方法的返回值更新到缓存中。

该注解用于更新缓存,无论结果是否已经缓存,都会在方法执行结束插入缓存,相当于更新缓存。一般用于更新方法之上。

2.2.1 主要属性

主要属性如下:

  • value:必填,指定缓存数据存放在哪块命名空间(缓存名)。用于指定要操作的缓存名称或缓存管理器的名称。可以是一个字符串,也可以是一个字符串数组,用于指定多个缓存名称。
  • cacheNames:与 value 差不多,二选一即可。
  • key:可选,指定缓存条目的键,用于唯一标识缓存中的条目。SpEL 表达式可以用于动态地生成键值。如果不指定 key,Spring Cache 将会使用默认的键生成策略来生成键值。
  • condition:条件符合则缓存。指定一个 SpEL 表达式,用于判断是否执行缓存操作。只有当表达式的值为 true 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • unless:条件符合则不缓存。指定一个 SpEL 表达式,用于判断是否不执行缓存操作。只有当表达式的值为 false 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • keyGenerator:指定一个自定义的键生成器,用于生成缓存条目的键值。默认为空,表示使用默认的键生成策略。key/keyGenerator二选一使用
  • cacheManager:指定一个自定义的缓存管理器,用于指定缓存的实现。默认为空,表示使用默认的缓存管理器。
  • cacheResolver:指定一个自定义的缓存解析器,用于解析缓存的实现。默认为空,表示使用默认的缓存解析器。
2.2.2 使用
    @CachePut(cacheNames = "userCache_", key = "#updateRequest.userId", unless = "#result == null")@Overridepublic UserDTO update2(UserUpdateRequest updateRequest) {Long id = updateRequest.getUserId();if (id == null || id <= 0) {return null;}// 修改用户信息UserDO updateDO = new UserDO();BeanUtils.copyProperties(updateRequest, updateDO);updateDO.setUpdateTime(LocalDateTime.now());userMapper.updateById(updateDO);// 演示效果UserDO userDO = userMapper.selectById(id);return do2DTO(userDO);}

注意:这里设置的 key一定要和执行缓存保存的方法设置 key一致,否则无法准确更新。

使用方法参数作为 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;}// 推荐使用@Cacheable(value="users", key="#user.id")public User find(User user) {return null;}@Cacheable(value="users", key="#p0.id")public User find(User user) {return null;}

除了上述使用方法参数作为 key之外,Spring还为我们提供了一个 root对象可以用来生成 key。通过该 root对象我们可以获取到以下信息。

在这里插入图片描述

2.3 @CacheEvict注解

@CacheEvict注解:删除缓存数据操作。

2.3.1 主要属性

主要属性如下:

  • value:必填,指定缓存数据存放在哪块命名空间(缓存名)。用于指定要操作的缓存名称或缓存管理器的名称。可以是一个字符串,也可以是一个字符串数组,用于指定多个缓存名称。
  • cacheNames:与 value 差不多,二选一即可。
  • key:可选,指定缓存条目的键,用于唯一标识缓存中的条目。SpEL 表达式可以用于动态地生成键值。如果不指定 key,Spring Cache 将会使用默认的键生成策略来生成键值。
  • condition:条件符合则缓存。指定一个 SpEL 表达式,用于判断是否执行缓存操作。只有当表达式的值为 true 时,才会执行缓存操作。默认为空,表示始终执行缓存操作。
  • eyGenerator:指定一个自定义的键生成器,用于生成缓存条目的键值。默认为空,表示使用默认的键生成策略。key/keyGenerator二选一使用。
  • cacheManager:指定一个自定义的缓存管理器,用于指定缓存的实现。默认为空,表示使用默认的缓存管理器。
  • cacheResolver:指定一个自定义的缓存解析器,用于解析缓存的实现。默认为空,表示使用默认的缓存解析器。
  • allEntries:是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存。
  • beforeInvocation:是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存。
2.3.2 使用
    @CacheEvict(value = "userCache_", key = "#id", condition = "#result.success == true")//@CacheEvict(value = "userCache_", allEntries = true)@Overridepublic BaseOperateResult deleteById(Long id) {BaseOperateResult operateResult = new BaseOperateResult();if (id == null || id <= 0L) {operateResult.setSuccess(false);operateResult.setErrorCode(DemoErrorCodeEnum.ID_IS_NOT_NULL.errorCode());return operateResult;}UserDTO oldDTO = getById(id);if (oldDTO == null) {operateResult.setSuccess(Boolean.FALSE);operateResult.setErrorCode(DemoErrorCodeEnum.RECORD_NOT_FOUND.errorCode());return operateResult;}// 不允许删除管理员账号if ("admin".equals(oldDTO.getUsername())) {operateResult.setSuccess(Boolean.FALSE);operateResult.setErrorCode(DemoErrorCodeEnum.NOT_DELETE_ADMIN_USER.errorCode());return operateResult;}// 用户逻辑删除UserDO updateDO = new UserDO();updateDO.setUserId(id);updateDO.setDelFlag(CommonConstants.DELETE_FLAG_DELETED);userMapper.updateById(updateDO);operateResult.setId(id);operateResult.setSuccess(true);return operateResult;}

注意:

  • 这里设置的 key一定要和执行缓存保存的方法设置 key一致,否则无法准确删除。
  • condition参数里的 #result为方法的返回值。所以,判断方法返回值的 success = true 时,则执行删除缓存操作。
  • 如果配置了 allEntries属性,则会删除 value为命名空间下的所有缓存条目的键,此时配不配 key属性都不会影响 allEntries属性操作。

3、全局配置Cache参数信息(了解)

参考文章:spring-boot+redis实现缓存功能:https://www.jianshu.com/p/be2c09cd27d8

项目配置文件(application.yml)中可以添加 cache配置信息。

注意:

  • 如果使用 Spring框架自动注入 CacheManager的方式,下面配置会生效。
  • 如果使用我们手动注入的自定义了 CacheManager方式,下面配置不会生效,而是使用我们自定义的相关配置。
spring:## Redis 配置信息redis:host: 127.0.0.1port: 6379password: xxxxxxdatabase: 1## Spring cache配置信息cache:# 缓存的类型,redistype: redisredis:# 缓存数据key是否使用前缀,默认是trueuse-key-prefix: true#缓存数据key的前缀,在上面的配置为true时有效,key-prefix: 'demo:'# redis中缓存超时的时间,默认60000mstime-to-live: 120000

参考文章:

  • SpEL表达式详解:https://blog.csdn.net/weixin_43888891/article/details/127520555

– 求知若饥,虚心若愚。

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

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

相关文章

Vue从入门到实战Day11

一、为什么要学Vue3 Vue3官网&#xff1a;简介 | Vue.js 1. Vue3的优势 2. Vue2选项式API vs Vue3组合式API 示例&#xff1a; 二、create-vue搭建Vue3项目 1. 认识create-vue create-vue是Vue官方新的脚手架工具&#xff0c;底层切换到了vite(下一代构建工具)&#xff0c;为…

jenkins插件之Warnings

Warnings插件&#xff0c;收集静态分析工具报告的编译器警告或问题&#xff0c;并将结果可视化。它内置了对许多编译器的支持&#xff08;cpp&#xff0c;clang&#xff0c;java等&#xff09;和工具&#xff08;spotbugs&#xff0c;pmd&#xff0c;checkstyle&#xff0c;esl…

Java操作Word文档,根据模板生成文件

Java操作Word文档 poi-tl介绍 官方文档&#xff1a;https://deepoove.com/poi-tl/ poi-tl&#xff08;poi template language&#xff09;是Word模板引擎&#xff0c;使用模板和数据创建很棒的Word文档。 在文档的任何地方做任何事情&#xff08;Do Anything Anywhere&#…

el-select可选择可搜索可输入新内容

需求&#xff1a;el-form-item添加el-select&#xff0c;并且el-select可选择可搜索可输入新内容&#xff0c;并且和其他的el-input做联动&#xff0c;如果是选择&#xff0c;那么el-input自动回填数据并且不可编辑&#xff0c;如果el-select输入新的内容&#xff0c;那么el-in…

【NumPy】关于numpy.transpose()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

如何使用 CapSolver 扩展找到 Google reCAPTCHA 站点密钥?

网站安全性在当今至关重要&#xff0c;Google reCAPTCHA 作为防止垃圾邮件和滥用行为的前线防御系统起着关键作用。reCAPTCHA 站点密钥是确保网站交互由人类驱动的唯一标识符。了解如何找到这个密钥对于网站管理员和开发人员来说至关重要。 什么是 reCAPTCHA 站点密钥 reCAPT…

MySQL主从复制(一):主备一致

MySQL主备的基本原理 如图所示就是基本的主备切换流程&#xff1a; 在状态1中&#xff0c; 客户端的读写都直接访问节点A&#xff0c; 而节点B是A的备库&#xff0c; 只是将A的更新都同步过来&#xff0c; 到本地执行。 这样可以保持节点B和A的数据是相同的。 当需要切换的时候…

spark的简单学习一

一 RDD 1.1 RDD的概述 1.RDD&#xff08;Resilient Distributed Dataset&#xff0c;弹性分布式数据集&#xff09;是Apache Spark中的一个核心概念。它是Spark中用于表示不可变、可分区、里面的元素可并行计算的集合。RDD提供了一种高度受限的共享内存模型&#xff0c;即RD…

IDEA连接MySQL后如何管理数据库

上一节讲解了IDEA如何连接MySQL数据库管理系统&#xff0c;接下来我们就可以在IDEA里使用MySQL来管理数据库了。那么如果我们现在还没有创建需要的数据库怎么办&#xff1f;本节就来教大家如何在IDEA连接MySQL后管理数据库(创建/修改/删除数据库、创建/修改/删除表、插入/更新/…

电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业电子招采平台

随着企业的快速发展&#xff0c;招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求&#xff0c;建立一个公平、公开、公正的采购环境至关重要。在这个背景下&#xff0c;我们开发了一款电子招标采购软件&#xff0c;以最大限度地控制采购成本&#…

【Vue2.x】props技术详解

1.什么是prop&#xff1f; 定义&#xff1a;组件标签上注册的一些自定义属性作用&#xff1a;向子组件传递数据特点 可以传递任意数量的prop可以传递任意类型的prop 2.prop校验 为了避免乱传数据&#xff0c;需要进行校验 完整写法 将之前props数组的写法&#xff0c;改为对象…

【SQL Server001】SQLServer2016常用函数实战总结(已更新)

1.熟悉、梳理、总结下SQL Server相关知识体系。 2.日常研发过程中使用较少&#xff0c;随着时间的推移&#xff0c;很快就忘得一干二净&#xff0c;所以梳理总结下&#xff0c;以备日常使用参考 3.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 总结源文件资源下载地址&am…

Ubuntu切换内核版本

#安装内核安装工具 sudo apt-get install software-properties-common sudo add-apt-repository ppa:cappelikan/ppa sudo apt-get update sudo apt-get install mainline#安装指定内核版本(有些版本并不能安装成功) mainline install 5.14.10#更新GRUB配置 sudo update-grub#查…

PE文件(六)新增节-添加代码

本节的目的是在所有节的空白区都不够存放我们要添加的代码时&#xff0c;教会我们新增一个足够大的节来添加代码 添加节 一.判断是否有足够的空间可以添加一个节表&#xff1a;新增节需要新增一个节表来记录此节信息 判断方法&#xff1a;SizeOfHeader - (DOS 垃圾数据 PE…

全网最全爬取-b站爬取弹幕+评论之js逆向与xml降本增效

&#x1f31f; ❤️ 作者&#xff1a;yueji0j1anke 首发于公号&#xff1a;剑客古月的安全屋 字数&#xff1a;801 阅读时间: 10min 声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及…

【C语言深度解剖】(14):结构体内存对齐(详细配图讲解)

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏链接查看&…

缩进在编程中的重要性及正确使用方法

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 前言 缩进不当引发的问题 缩进的正确使用方法 缩进错误的调试与修复 总结 前言 在编程世…

Unity 资源 之 限时免费的Lowpoly农场动物,等你来领!

Unity资源 之 Lowpoly farm animals 农村动物 前言资源包内容领取兑换码 前言 Unity 资源商店为大家带来了一份特别的惊喜——限时免费的农场动物资源&#xff01;这是一个充满趣味和实用性的资源包。 资源包内容 在这个资源包中&#xff0c;你可以找到丰富多样的低地养殖动物…

Vue3路由配置

路由其实就是一组对应关系&#xff0c;将一个路径与一个组件对应起来&#xff0c;当路径发生变化&#xff0c;路由器就可以通过路由规则&#xff0c;找到当前路径对应的组件&#xff0c;并将该组件呈现到页面上 使用路由步骤&#xff1a; 1.终端输入 npm i vue-router 2.在App…

Softing工业将亮相2024年阿赫玛展会——提供过程自动化的连接解决方案

您可于2024年6月10日至14日前往美因河畔法兰克福11.0号馆&#xff0c;Softing将在C25展位展出&#xff0c;欢迎莅临&#xff01; 作为工业应用中数据交换领域公认的专家&#xff0c;Softing工业致力于帮助各行各业的客户部署网络自动化和优化生产流程。 使用Softing产品&…