Spring @Cacheable缓存注解

一、简介

缓存介绍

缓存,在我们的日常开发中用的非常多,是我们应对各种性能问题支持高并发的一大利器。

  • Spring 从 3.1 开始就引入了缓存的支持。定义了如下两个接口来统一支持不同的缓存技术。

    • org.springframework.cache.Cache
    • org.springframework.cache.CacheManager
  • 我们熟知的缓存有:堆缓存(Ehcache3.xGuava CacheCaffeine等)、堆外缓存(Ehcache3.xMapDB等)、分布式缓存(RedisMemcached等)等等。

  • 常用的缓存注解:@EnableCaching@Cacheable@CachePut@CacheEvict

Cache 和 CacheManager 接口说明

  • Cache 接口包含缓存的各种操作集合,你操作缓存就是通过这个接口来操作的。
  • Cache 接口下 Spring 提供了各种 xxxCache 的实现,比如:RedisCache、EhCache、ConcurrentMapCache等。
  • CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache。这些 Cache 存在于 CacheManager 的上下文中。

二、缓存实战

1.开启缓存

在 SpringBoot 的启动类上添加注解@EnableCaching

2.@Cacheable

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存。

常用属性:

  • cacheNamesvalue:用来指定缓存组件名称。

    @Cacheable(cacheNames = "users", key="#id")
    public User getUser(Integer id) {}
    
  • key:缓存数据的 key,可以用它来指定。默认使用所有参数的值进行组合。(key可以使用 spEL 表达式来编写)。

    @Cacheable(cacheNames = "usersBySpEL", key="#root.methodName + '[' + #id + ']'")
    public User getUserBySpEL(Integer id) {}
    
  • keyGenerator:key 的生成器。key 和 keyGenerator 二选一使用。

    @Cacheable(cacheNames = "userByKeyGenerator", keyGenerator = "myKeyGenerator")
    public User getUserByKeyGenerator(Integer id) {}
    
  • condition:指定符合条件的情况下才缓存。

    @Cacheable(cacheNames = "userByCondition", condition = "#id > 1")
    public User getUserByCondition(Integer id) {}
    
  • unless:指定不符合条件的情况下才缓存。(可以获取到结果进行判断,通过 #result 获取方法结果,unless,汉语意思,除非,指会缓存,除了。。。之外)。

    @Cacheable(cacheNames = "userByUnless", unless = "#id > 1")
    public User getUserByUnless(Integer id) {}
    
  • sync:是否使用异步模式。

3.@CachePut

@CachePut 的作用 主要针对配置,能够根据方法的请求参数对其结果进行缓存。

  • 区别于 @Cacheable,它每次都会触发真实方法的调用,可以保证缓存的一致性。
  • 属性与 @Cacheable 类同。
@CachePut(cacheNames = "users" , key = "#user.id")
public User addUser(User user) {}
4.@CacheEvict

@CacheEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

常用属性

  • cacheNamesvalue:用来指定缓存组件名称。
  • key:缓存数据的 key,可以用它来指定。默认使用所有参数的值进行组合。(key可以使用 spEL 表达式来编写)。
  • condition:指定符合条件的情况下的缓存。
  • allEntries:是否清空所有缓存,缺省为false。
  • beforeInvocation:是否在方法执行前就清空,缺省为false,缺省情况下,如果方法执行抛异常,则不会清空缓存。
@CacheEvict(cacheNames = "users", key = "#id")
public void delUserCache(Integer id) {}
5.@CacheConfig

@CacheConfig 的作用 主要针对类配置,能够设置当前类中 @Cacheable 的 value 属性默认值。当然如果 @Cacheable 设置了 value,还是以设置的值为准。

常用属性

  • cacheNames: 指定缓存名称默认值。
6.@Caching

@Caching 的作用 主要针对方法配置,能够组合多个Cache注解。比如用户新增成功后,我们可能需要添加 id -> user、username -> user、email -> user 的缓存,此时就需要 @Caching 组合多个注解标签了。

常用属性

  • cacheable:组合多个 @Cacheable 注解
  • put:组合多个 @CachePut 注解
  • evict:组合多个 @CacheEvict 注解
@CacheConfig(cacheNames = "users")
public class CacheTestServiceImpl implements CacheTestService {/*** @Cacheable 的 cacheNames 默认为 "users"*/@Cacheable(key="#id")public User getUser(Integer id) {...}
}
7.自定义缓存过期时间

7.1 设置全局默认缓存过期时间:

    // 提供默认的cacheManager,应用于全局,实现存活2天@Bean@Primarypublic CacheManager defaultCacheManager(RedisTemplate<?, ?> redisTemplate) {RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(redisTemplate.getConnectionFactory());RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(2));return new RedisCacheManager(writer, config);}

7.2 定制部分缓存过期时间

  • 定制缓存过期时间,需要自定义RedisCacheManager来实现ttl设置。
  • 注意:项目中如已配置了RedisCacheManager需要在原配置的bean上添加注解 @Primary,以免造成干扰
	/**自定义RedisCacheManager,用于在使用@Cacheable时设置ttl*/@Beanpublic RedisCacheManager selfCacheManager(RedisTemplate<String, Object> redisTemplate) {RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));return new SelfRedisCacheManager(redisCacheWriter, redisCacheConfiguration);}

SelfRedisCacheManager.java

public class SelfRedisCacheManager extends RedisCacheManager {public SelfRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {super(cacheWriter, defaultCacheConfiguration);}@Overrideprotected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {String[] cells = StringUtils.delimitedListToStringArray(name, "=");name = cells[0];if (cells.length > 1) {long ttl = Long.parseLong(cells[1]);// 根据传参设置缓存失效时间,默认单位是秒cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));}return super.createRedisCache(name, cacheConfig);}
}

使用:

// value、cacheNames是等效的,ttl=600s,unless是不缓存的结果(为null时不缓存)
@Cacheable(value = "p_user=600",key = "#menu+'_'+#type+'_'+#userId",cacheManager = "selfCacheManager", unless = "#result == null")
public User getUser(...){xxx
}// 当前方法执行时对应的key失效,也可以用@CachePut在当前方法执行时更新key
@CacheEvict(cacheNames = "p_user",key = "#p.menu+'_'+#p.type+'_'+#p.user")
public boolean setUser(User p){xxx
}

三、spEL表达式

spEL表达式

参考地址:
1.@Cacheable设置过期时间:https://blog.csdn.net/weixin_41860719/article/details/125226096

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

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

相关文章

这个sql有点东西,记录一下

我有一个需求&#xff1a;在订单表里面查询指定时间的订单数据&#xff0c;如果要是没有订单的话&#xff0c;需要展示当天日期和数据&#xff0c;数据为0 先看一下效果&#xff1a; 话不多说&#xff0c;直接上SQL SELECTdate_range.date AS 日期,COUNT( oco.id ) AS 总订单…

Hdoop学习笔记(HDP)-Part.14 安装YARN+MR

十四、安装YARNMR 1.MR中间结果存储权限 使用Yarn提交MapReduce任务的时候&#xff0c;中间结果会保存在HDFS&#xff0c;/user/username/&#xff0c;如果/user目录下用户目录下不存在&#xff0c;则被创建&#xff0c;当MR执行结束之后&#xff0c;中间结果会被删除&#x…

【多线程】-- 08 线程状态观测、线程优先级、守护线程

多线程 5 线程状态 5.5 线程状态观测 Thread.State线程可以处于以下状态之一&#xff1a; NEW&#xff1a;尚未启动的线程处于此状态RUNNABLE&#xff1a;在Java虚拟机中执行的线程处于此状态BLOCKED&#xff1a;被阻塞等待监视器锁定的线程处于此状态WAITING&#xff1a;正…

英语助教求职简历模板(通用10篇)

以下10篇简历内容以英语助教招聘需求为背景制作&#xff0c;大家可以借鉴参考&#xff0c;希望能帮助大家在众多候选人中脱颖而出。 英语助教求职简历下载&#xff08;可在线制作)&#xff1a;百度幻主简历 英语助教简历1&#xff1a; 求职意向 求职类型&#xff1a;全职 …

Jmeter分布式压测

一、jmeter为什么要做分布式压测 jmeter本身的局限性 一台压力机的 Jmeter 支持的线程数受限于 Jmeter 其本身的机制和硬件配置&#xff08;内存、CPU等&#xff09;是有限的由于 Jmeter 是 Java 应用&#xff0c;对 CPU 和内存的消耗较大&#xff0c;在需要模拟大量并发用户…

GPT市场将取代插件商店 openAI已经关闭plugins申请,全部集成到GPTs(Actions)来连接现实世界,可以与物理世界互动了。

Actions使用了plugins的许多核心思想&#xff0c;也增加了新的特性。 ChatGPT的"Actions"与"Plugins"是OpenAI在GPT模型中引入的两种不同的功能扩展机制。这两种机制的目的是增强模型的功能&#xff0c;使其能够处理更多样化的任务和请求。下面是对两者的比…

熬夜会秃头——Beta冲刺总结随笔

这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标总结Beta冲刺团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 目录 一、Beta冲刺开始前设立的任务完成…

VMware虚拟机搭建+云平台购买搭建(阿里云+UCloud)【设置主机名以及主机名映射、配置免密登录、配置JDK】

本地虚拟机的搭建 一、准备网段 在VMware的虚拟网络编辑器中将VMnet8虚拟网卡的 网段设置为&#xff1a;192.168.88.0网关设置为&#xff1a;192.168.88.2 二、下载CentOS操作系统文件&#xff0c;并安装 三、克隆多台虚拟机 依照同样的方法&#xff0c;克隆出node2…

设计模式精讲:掌握工厂方法与抽象工厂的精髓

设计模式精讲&#xff1a;掌握工厂方法与抽象工厂的精髓 一、引言&#xff1a;如何学习设计模式&#xff1f;二、工厂方法&#xff08;也叫工厂模式&#xff09;2.1、代码结构2.2、符合的设计原则2.3、小结 三、抽象工厂3.1、代码结构3.2、符合的设计原则3.3、小结 总结 一、引…

rust持续学习 COW

COW我第一次看见还以为是奶牛 很奇怪是个啥 后来了解到是clone on write 缩写的&#xff0c;大乌龙啊 这个有两种enum,一种是borrow&#xff0c;一种是own rust中&#xff0c;数据读写经常涉及到所有权 这个borrow&#xff0c;很显然&#xff0c;就是不可变借用了 own就是可以写…

北邮22级信通院数电:Verilog-FPGA(12)第十二周实验(2)彩虹呼吸灯

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 二.管脚分配 三.实验效果 一.代…

大势智慧荣获2023光合组织解决方案大赛人工智能赛道标杆奖及争先奖!

近日&#xff0c;2023年第三届光合组织解决方案大赛获奖名单正式公布。大势智慧以基于国产化平台的实景三维全流程解决方案&#xff0c;突破层层选拔&#xff0c;最终荣获“集智计划”&#xff08;人工智能赛道&#xff09;标杆奖及争先奖。 实景三维是我国的数字基础设施&…

【Go】protobuf介绍及安装

目录 一、Protobuf介绍 1.Protobuf用来做什么 2. Protobuf的序列化与反序列化 3. Protobuf的优点和缺点 4. RPC介绍 <1>文档规范 <2>消息编码 <3>传输协议 <4>传输性能 <5>传输形式 <6>浏览器的支持度 <7>消息的可读性和…

R语言实验三

1、读取一个文件并进行如下操作。 ①使用命令清空工作空间&#xff0c;使用read.table读取exam_1.txt文件&#xff0c;将文件保存到data变量中&#xff0c;数据第一行设置为列名&#xff0c;第一列是行名。 ②判断对象data是否为矩阵。 ③将对象转换为矩阵&#xff0c;记为d…

【SpringBoot3+Vue3】七【后续2】【番外篇】- (使用docke部署)

目录 一、maven打包后端服务 1、clean 2、package 3、查看jar包 二、部署java后端服务 1、使用dockerfile构建一个java17的镜像 1.1 使用dokcerfile构建容器命令 1.2 方式一 将jar打包进容器镜像 1.3 方式二 jar不打包进容器镜像&#xff0c;通过映射主机目录映射方式…

mysql 查询提取json 并去除双引号

1.建表语句 CREATE TABLE uset_test_demo (id bigint(20) NOT NULL AUTO_INCREMENT,context text,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT4 DEFAULT CHARSETutf8;2.源数据 {"title": "Harry Potter","author": "J.K. Rowling&qu…

Linux基础项目开发1:量产工具——文字系统(四)

前言&#xff1a; 前面我们已经把显示系统&#xff0c;输入系统的框架搭建好了&#xff0c;那么有了输入和显示&#xff0c;显示的内容应该是什么呢&#xff1f;这节就要让我们一起对显示的内容&#xff0c;文字系统进行搭建。 目录 一、数据结构抽象 1.描述一个文字的位图&a…

ubuntu系统下搭建本地物联网mqtt服务器的步骤

那么假如我们需要做一些终端设备&#xff0c;例如温湿度传感器、光照等物联网采集设备要接入呢&#xff1f;怎么样才能将数据报送到服务器呢&#xff1f; 以下内容基于我们ubuntu系统下的emqx成功启动的基础上。我们可以用浏览器键入控制板的地址&#xff0c;如果启动成功&…

特征相关性计较

Pearson相关系数 用于度量两个连续型变量之间的线性关系。取值范围在-1到1之间&#xff0c;0表示无线性关系&#xff0c;1表示完全正相关&#xff0c;-1表示完全负相关 import pandas as pd# 创建一个包含两个连续型变量的DataFrame data {Variable1: [1, 2, 3, 4, 5],Vari…