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

Springboot整合SpringCache+redis简化缓存开发

使用步骤:

1.引入依赖

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

2.写配置,在配置文件配置使用redis作为缓存

spring.cache.type=redis
#指定缓存过期时间,单位毫秒
spring.redis.time-to-live=3600000

引入的上面依赖后CacheAutoConfiguration会导入RedisCacheConfiguration,自动配置RedisCacheManager; 

3.在启动类添加下面的注解开启缓存功能:

@EnableCaching

完成以上配置后,就可以使用注解为简化redis缓存管理,下面是一些常用到的注解:

@Cacheable:触发将数据保存到缓存中;

@CacheEvict:触发将数据从缓存中删除;

@CachePut:使用不影响方法执行的方式更新缓存;

@Caching:组合以上多个操作;

@CacheConfig:在类级别共享缓存的相同配置。

4.在需要缓存中的方法上添加对应的注解

@Cacheable({"category"})
@Override
public List<CategoryEntity> getLevel1Categorys() {//此处省略具体业务逻辑
}

如果使用上面的方式声明缓存,SpringCache会有以下默认行为:

  • 如果缓存中已存在该数据,方法不再执行,直接查询缓存返回;
  • key默认自动生成,生成的规则为缓存的名字::SimpleKey[](自主生成的key值),如下图
  • 缓存的value值,默认使用jdk序列化机制,将序列化的数据存到redis; 
  • 默认ttl时间为-1,即永不过期。

如果要想自己定义一些规则,SpringCashe是支持的:
指定key名字,使用key属性,接受spEl表达式,spEl支持的表达式详见官方文档;

注意spEl表达式如果是普通字符串,一定要带单引才生效

普通字符串不带单引号,不生效:

@Cacheable(value = {"category"},key = "level1Categorys") ✘

普通字符串带单引号,生效:

@Cacheable(value = {"category"},key = "'level1Categorys'") ✔

指定缓存的存活时间ttl,在appliaction配置文件中配置,参见上文描述;

将数据保存为json格式,方便不同编程语言解析,如果想实现这一步,需添加自定义配置,参考如下代码:

@Configuration
@EnableCaching  //将启动类的开启注解移到这方便统一管理
public class MyCacheConfig {@Beanpublic RedisCacheConfiguration cacheConfiguration(){RedisCacheConfiguration config=RedisCacheConfiguration.defaultCacheConfig();config=config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));config=config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));return config;}
}

注意,如果开启了Spring Cache自定义缓存,那么Spring只会来读取自定义缓存的内容,对于自定义缓存中没有的内容,将会缺失。像上面代码只配置了key和value序列化规则,没有配置缓存过期时间,即使配置文件配置了,不会读取,为了避免这个问题,对上面的方法进行升级如下:

@Configuration
@EnableCaching
public class MyCacheConfig {@Beanpublic RedisCacheConfiguration cacheConfiguration(CacheProperties cacheProperties){RedisCacheConfiguration config=RedisCacheConfiguration.defaultCacheConfig();config=config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));config=config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));CacheProperties.Redis redisProperties= cacheProperties.getRedis();//如果配置文件配置了过期时间,则读取if(redisProperties.getTimeToLive()!=null){config=config.entryTtl(redisProperties.getTimeToLive());}if(redisProperties.getKeyPrefix()!=null){   //如果配置文件配置了key前缀,则读取config=config.prefixKeysWith(redisProperties.getKeyPrefix());}if(!redisProperties.isCacheNullValues()){// //如果配置文件配置了不缓存空值,则禁用空值缓存config=config.disableCachingNullValues();}if(!redisProperties.isUseKeyPrefix()){  //如果配置文件配置禁用禁用key,则禁用config=config.disableKeyPrefix();}return config;}
}

附SpringCashce 在application.yml中的完整配置:

#上面还有spring在最左侧cache:type: redisredis:#设置缓存过期时间,单位mstime-to-live: 3600000#开启缓存null值,可防止缓存穿透cache-null-values: true#开启key前缀 不推荐,建议设置成falseuse-key-prefix: true#定义key前缀,不推荐,建议使用缓存分区#key-prefix: CACHE_

如果想在修改数据时触发对缓存的删除,在方面上方添加@CacheEvict并批量缓存分区即可。

如果想在修改时对多个缓存进行批量操作,可以使用下面两种方法中任一种:

@Caching(evict = {@CacheEvict(value = {"category"},key = "'level1Categorys'"),@CacheEvict(value = {"category"},key = "'getCatelogJson'"),})

value为设置缓存时指定的分区的名字,key为设置缓存时定义的方法名

方法二:

    @CacheEvict(value = "category",allEntries = true)

value为设置缓存时指定的分区的名字,allEntries设置为true,当标注有上面注解的方法被调用,数据修改时,指定缓存分区categorys的缓存都会被删除,当有请求再次添加缓存时,缓存分区categorys的所有数据会再次添加到缓存中。附设置缓存的方法

    @Cacheable(value = {"category"},key = "'level1Categorys'")@Overridepublic List<CategoryEntity> getLevel1Categorys() {//此处省略方法具体实现,重点在缓存注解声明}@Cacheable(value = {"category"},key = "#root.methodName")@Overridepublic Map<String,  List<Catelog2Vo>> getCatelogJson() {//此处省略方法具体实现,重点在缓存注解声明}

PS:存储同一类型的数据,可放到到同一分区,即@Cacheable注解里value的值。如此在redis缓存分区就有层次分明的结构了,这在缓存多的情况下,非常有用,能快速找到相关缓存,方便统一管理。

@注意@CacheEvict采用的是缓存一致性里的失效模式,@CachePut属于双写模式。

SpringCache有其优越之处,但存在一定的不足。

如SpringCache默认是不加锁的,要想解决缓存击穿问题,在使用时只有@Cacheable注解可配置sync属性的值为true加锁,其他注解不支持配置加锁,示例:

    @Cacheable(value = {"category"},key = "'level1Categorys'",sync = true)@Overridepublic List<CategoryEntity> getLevel1Categorys() {}

因此,要结合具体业务情况来看是否采用。

SpringCache适用场景:常规数据(读多写少,即时性、一致性要求不高的数据)

而对于即时性和数据一致性要求高的场景需要进行特殊设计,如引入读写锁,引入canal。

相关文章:

Springboot整合SpringCache+redis简化缓存开发

使用步骤&#xff1a; 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupI…...

关于EOF标识符

EOF的概念 EOF是C语言中表示文件结束的标志符号&#xff0c;通常被定义为-1&#xff0c;它用于指示已到达文件的末尾或输入流的末尾。 EOF的使用 在输入操作中&#xff0c;EOF常常用于判断是否到达了文件末尾或输入流末尾&#xff0c;以便终止读取操作。例如&#xff0c;在使…...

家用洗地机排行榜前十名:2024十大王牌机型精准种草

最近很多人都在问我洗地机相关的问题&#xff0c;不愧是改善家庭生活品质的“三神器”之一。洗地机依靠其清洁力和清洁效率吸引了越来越多的平时需要做家务人群的兴趣&#xff0c;为了解答大家关于洗地机的各种疑问&#xff0c;我把市面上目前非常火爆的洗地机型号和参数都进行…...

【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储

最近俺在接触 Chrome 插件开发&#xff0c;需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂&#xff0c;它包含一个 Map 和一个数组。我使用 chrome.storage.local API来存储这个数据&#xff0c;然后在另一个地方获取数据。保存数据的代码并没有报错&#xff0c;但…...

MySQL 保姆级教程(二):使用 MySQL 检索数据

使用 MySQL 3.2 选择数据库 使用数据库: 输入: USE 数据库名;输出: Database changed分析: 不返回任何结果&#xff0c;显示某种形式的通知 ​ 例如: 使用 crashcourse 数据库 use crashcourse; 3.3 了解数据库和表 列出所有的数据库: 输入: SHOW DATABASES;输出: --------…...

Sui Bridge在测试网上线并推出10万SUI激励计划

是一种为Sui设计的原生桥接协议&#xff0c;专门用于在Sui与其他网络之间桥接资产和数据。今天&#xff0c;Sui Bridge宣布在测试网上线。作为一种原生协议&#xff0c;Sui Bridge能够在Ethereum和Sui之间轻松且安全地转移ETH、wBTC、USDC和USDT&#xff0c;使其成为Sui基础设施…...

Spring系统学习 - Bean的作用域

bean作用域介绍 Spring框架提供了不同的作用域来管理Bean的生命周期和可见性&#xff0c;这对于控制不同类型的组件和处理并发请求尤其重要。 singleton&#xff08;默认&#xff09;&#xff1a; 每个Spring IoC容器只有一个bean实例。当容器创建bean后&#xff0c;它会被缓存…...

贪吃蛇双人模式设计(2)

敲上瘾-CSDN博客控制台程序设置_c语言控制程序窗口大小-CSDN博客贪吃蛇小游戏_贪吃蛇小游戏csdn-CSDN博客 一、功能实现&#xff1a; 玩家1使用↓ → ← ↑按键来操作蛇的方向&#xff0c;使用右Shift键加速&#xff0c;右Ctrl键减速玩家2使用W A S D按键来操作蛇的方向&am…...

mysql什么时候不需要建立索引

WHERE 条件&#xff0c;GROUP BY&#xff0c;ORDER BY 里用不到的字段&#xff0c;索引的价值是快速定位&#xff0c;如果起不到定位的字段通常是不需要创建索引的&#xff0c;因为索引是会占用物理空间的。字段中存在大量重复数据&#xff0c;不需要创建索引&#xff0c;比如性…...

热门开源项目推荐:技术与地址概览

随着开源项目的不断兴起&#xff0c;越来越多的优秀项目涌现出来&#xff0c;为开发者们提供了丰富的资源和灵感。在此&#xff0c;我将为大家推荐几个热门的开源项目&#xff0c;并附上它们的开源地址&#xff0c;以供大家参考和了解。 1. TensorFlow 项目简介&#xff1a; …...

Golang的channel

目录 基本使用 channel 数据结构 阻塞的协程队列 协程节点 构建 channel 写流程 读流程 非阻塞与阻塞 closechan(关闭) 基本使用 创建无缓存 channel c : make(chan int) //创建无缓冲的通道 cc : make(chan int,0) //创建无缓冲的通道 c 创建有缓存 channel c : m…...

DIYGW可视化开发工具:微信小程序与多端应用开发的利器

一、引言 随着移动互联网的飞速发展&#xff0c;微信小程序以其轻便、易用和跨平台的特点受到了广泛关注。然而&#xff0c;微信小程序的开发相较于传统的H5网页开发&#xff0c;在UI搭建和交互设计上存在一定的挑战。为了应对这些挑战&#xff0c;开发者们一直在寻找更加高效…...

docker——基础知识

简介 一、什么是虚拟化和容器化 ​ 实体计算机叫做物理机&#xff0c;有时也称为寄主机&#xff1b; ​ 虚拟化&#xff1a;将一台计算机虚拟化为多台逻辑计算机&#xff1b; ​ 容器化&#xff1a;一种虚拟化技术&#xff0c;操作系统的虚拟化&#xff1b;将用户空间软件实…...

SAP MMRV/MMPV 物料账期月结月底月初开关

公告&#xff1a;周一至周五每日一更&#xff0c;周六日存稿&#xff0c;请您点“关注”和“在看”&#xff0c;后续推送的时候不至于看不到每日更新内容&#xff0c;感谢。 这是一条刮刮乐&#xff0c;按住全部选中&#xff1a;点关注的人最帅最美&#xff0c;欢迎&#xff1…...

五分钟看懂如何解决FP独立站的广告投放问题

在数字化时代的浪潮中&#xff0c;跨境电商的独立站成为了商家们的新宠。与传统的电商平台相比&#xff0c;独立站在品牌建设、市场定位以及客户体验上提供了更多的自由度和创新空间。然而&#xff0c;这些独立站尤其是销售FP产品的站点&#xff0c;在广告投放上遇到了重重障碍…...

学习分享-FutureTask

前言 今天再改简历的时候回顾了之前实习用到的FutureTask&#xff0c;借此来回顾一下相关知识。 FutureTask 介绍 FutureTask 是 Java 并发包&#xff08;java.util.concurrent&#xff09;中的一个类&#xff0c;用于封装异步任务。它实现了 RunnableFuture 接口&#xff0…...

Javaweb02-XML概述

第一章 XML概述 1.XML基本概念 什么是xml&#xff1f; **a.**引入的原因&#xff1a;为了解决不同不同语言之间的数据传输的格式不同 **b.**概念&#xff1a;XML是一种可扩展标记语言&#xff0c;适用于不同数据之间的数据交换 **c.**XML文档&#xff1a;通过元素的嵌套&a…...

Linux shell编程基础

Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问 Linux 内核的服务。 Shell 脚本&#x…...

2024.6.12 作业 xyt

今日课堂练习&#xff1a;vector构造函数 #include <iostream> #include <vector> using namespace std;void printVector(vector<int> &v) {vector<int>::iterator iter;for(iterv.begin(); iter ! v.end(); iter){cout << *iter <<…...

QTTabBar在重置Internet Explorer后失效

网上常见的办法是&#xff1a; 打开IE浏览器>>设置>>Internet选项>>高级。勾选启用第三方浏览器扩展&#xff0c;重启后生效。 打开IE浏览器-设置–管理加载项&#xff0c;启用QTTabBar。 实际在Win10上使用的时候会遇到点开IE自动跳转到Edge的问题。这时…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...