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.rhkb.cn/news/330381.html

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

相关文章

机器学习实验 --- 逻辑回归

第1关:逻辑回归核心思想 任务描述 本关任务:根据本节课所学知识完成本关所设置的编程题 #encoding=utf8 import numpy as npdef sigmoid(t):完成sigmoid函数计算:param t: 负无穷到正无穷的实数:return: 转换后的概率值:可以考虑使用np.exp()函数#********** Begin *******…

C语言-atoi()库函数的模拟实现

文章目录 前言一、atoi()库函数的介绍及使用1.1 atoi()库函数介绍1.2 atoi()库函数使用 二、atoi()库函数的模拟实现2.1 函数设计2.2 函数实现思路2.3 具体实现2.4 测试 总结 前言 本篇文章介绍c语言中库函数atoi()的使用&#xff0c;以及模拟实现库函数。 一、atoi()库函数的…

景源畅信电商:抖店需要的成本高吗?

在数字化时代的浪潮中&#xff0c;短视频平台迅速崛起&#xff0c;成为连接用户与商家的新桥梁。抖音作为其中的佼佼者&#xff0c;不仅改变了人们的娱乐方式&#xff0c;也催生了新型的电商模式——抖店。许多人好奇&#xff0c;入驻这样一个充满活力的平台&#xff0c;需要承…

【数据结构】第七节:堆

个人主页&#xff1a; 深情秋刀鱼-CSDN博客 数据结构专栏&#xff1a;数据结构与算法 源码获取&#xff1a;数据结构: 上传我写的关于数据结构的代码 (gitee.com) ​ 目录 一、堆 1.堆的概念 2.堆的定义 二、堆的实现 1.初始化和销毁 2.插入 向上调整算法 3.删除 向下调整算法…

DDoS攻击的最新动态及市场趋势分析

随着数字化转型的加速和网络连接设备的增加&#xff0c;分布式拒绝服务(Distributed Denial of Service, DDoS)攻击已经成为全球网络安全领域的一大威胁。根据最新的市场研究报告&#xff0c;预计到2028年&#xff0c;DDoS防护软件市场的复合年增长率将达到14%以上&#xff0c;…

Threes 特效 炫酷传送门HTML5动画特效

基于Three.js的HTML5 3D动画&#xff0c;这个动画模拟了游戏中的一个炫酷的3D场景&#xff0c;支持360度视角查看&#xff0c;也支持鼠标滚轮进行缩放。画面中主要展现了一个游戏中传送门的效果&#xff0c;同时还有路两边的围栏、灯笼、石头&#xff0c;以及星光闪闪的萤火虫&…

springboot vue 开源 会员收银系统 (2) 搭建基础框架

前言 完整版演示 前面我们对会员系统https://blog.csdn.net/qq_35238367/article/details/126174288进行了分析 确定了技术选型 和基本的模块 下面我们将从 springboot脚手架开发一套收银系统 使用脚手架的好处 不用编写基础的rabc权限系统将工作量回归业务本身生成代码 便于…

宿舍管理系统--毕业设计

毕业设计&#x1f4bc;MD5加密&#x1f512;SSM框架&#x1f3a8;Layui框架&#x1f384; 实现功能 管理员的登录与登出 管理员,班级,学生,宿舍&#xff0c;卫生&#xff0c;访客各模块增删改查 个别模块关联查询 各个模块数据导出Excel 一些截图

双向链表C++,C#,Java版,这些程序大多已经过测试,一直在用。

先C版吧&#xff0c;我最先用的是C#,后来是Java&#xff0c;后来改用C版的&#xff0c;因为现在一直在用C&#xff0c;单链 表一直没写上去&#xff0c;因为我很少用&#xff0c;用的是双链表。 执行代码例子1&#xff1a; int main() { _DList<_string> s…

重学java 40.多线程 — 死锁和线程状态

—— 24.5. 一、死锁 1.死锁介绍&#xff08;锁嵌套就有可能产生死锁&#xff09; 指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁 例&#xff1a; 两线程处于互相等待的状态&a…

nss刷题(3)

1、[SWPUCTF 2021 新生赛]include 根据提示传入一个file后显示了关于flag的代码 这是一个文件包含&#xff0c;考虑php伪协议&#xff0c;构造payload&#xff1a; ?filephp://filter/readconvert.base64-encode/resourceflag.php 2、[SWPUCTF 2021 新生赛]Do_you_know_http …

MyBatisPlus使用流程

引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version> </dependency> 版本号根据需要选取 在实体类上加注解声明&#xff0c;表信息 根据数…

go-zero 实战(5)

引入Prometheus 用 Prometheus 监控应用 1. 用 docker 启动 Prometheus 编辑配置位置&#xff0c;我将 prometheus.yaml 和 targets.json 文件放在了 /opt/prometheus/conf目录下 prometheus.yaml global:scrape_interval: 15s # 抓取间隔evaluation_interval: 15s # 评估…

网络拓扑—DHCP服务配置

文章目录 DHCP服务搭建相关配置细节前提安装DHCP服务 DHCP服务搭建 相关配置细节前提 系统&#xff1a;Windows Server 2003 IP网段&#xff1a;10.0.0.0/24 三台机子&#xff1a; 普通PC机 DHCP服务器 路由器&#xff08;两块网卡&#xff0c;连接内外网&#xff09; //注…

中国主要城市房价指数数据集(2011-2024)

数据来源&#xff1a;东方财富网 时间跨度&#xff1a;2011年1月 - 2024年4月 数据范围&#xff1a;中国主要城市 包含指标&#xff1a; 日期、城市 新建商品住宅价格指数-同比 新建商品住宅价格指数-环比 新建商品住宅价格指数-定基 二手住宅价格指数-环比 二手住宅价格指…

get和post的区别,二者是幂等的吗?

一、什么是幂等 所谓幂等性通俗的将就是一次请求和多次请求同一个资源产生相同的副作用。 维基百科定义&#xff1a;幂等&#xff08;idempotent、idempotence&#xff09;是一个数学与计算机学概念&#xff0c;常见于抽象代数中。 在编程中一个幂等操作的特点是其任意多次执…

Docker(四) 文件和网络

1 Dockerfile 1.1 什么是Dockerfile Dockerfile是一个文本文件&#xff0c;包含一系列命令&#xff0c;这些命令用于在 Docker 镜像中自动执行操作。Dockerfile 定义了如何构建 Docker 镜像的步骤和所需的操作。 Dockerfile 中包含的命令可以设置和定制容器的环境&#xff0c;…

优于InstantID!中山大学提出ConsistentID:可以仅使用单个图像根据文本提示生成不同的个性化ID图像

给定一些输入ID的图像&#xff0c;ConsistentID可以仅使用单个图像根据文本提示生成不同的个性化ID图像。效果看起来也是非常不错。 相关链接 Code:https://github.com/JackAILab/ConsistentID Paper&#xff1a;https://ssugarwh.github.io/consistentid.github.io/arXiv.pd…

一文带你入门ini格式

引入: 以蜂鸣器为例&#xff0c;每次我们增加新的设备&#xff0c; 都需要添加两个新文件: 修改程序代码&#xff0c;手动添加: 缺点: 不利于维护 设备类节点直接通过ini文件配置 什么是.ini文件 ini文件通常以纯文本形式存在&#xff0c;并且包含了一个或多个节&#xff08;se…

java技术:spring-secrity实现认证、授权

目录 一、依赖 二、逻辑图 三、代码设计 1、WebSecurityConfigurerAdapter的实现类 2、设计登录接口 config配置&#xff1a; 1&#xff09;UserDetailsService实现类重写&#xff1a; 2&#xff09;书写登录实现类&#xff08;调用authenticationManager、可以与后面的…