spring cache(一)介绍

server/2024/9/20 7:27:26/ 标签: spring, java, mybatis

一、介绍

1、背景

项目中使用最多的缓存技术就是Redis,用Redis就可以实现了,为什么需要使用spring cache?

先看下我们使用缓存步骤:

(1)查寻缓存中是否存在数据,如果存在则直接返回结果

(2)如果不存在则查询数据库,查询出结果后将结果存入缓存并返回结果

(3)数据更新时,先更新数据库

(4)然后更新缓存,或者直接删除缓存

可以看到逻辑都差不多,这样就出现大量重复的代码,而且缓存与业务耦合较深。Spring Cache则解决了这个问题,它利用AOP实现了基于注解的缓存功能,并且进行了合理的抽象,业务代码不用关心底层是使用了什么缓存框架,只需要简单地加一个注解,就能实现缓存功能了。

2、简介

spring cache官网Cache Abstraction :: Spring Framework

spEl语法说明==>官方文档 

3、默认配置

在默认配置下,

springcache缓存的是用jdk序列化过的数据,我们通常是缓存Json字符串,因为使用Json能跨语言,跨平台进行交互,;

我们也可以修改他的默认配置,包括ttl(过期时间)、存储格式等。

 二、原理

流程说明:
 CacheAutoConfiguration  =>  RedisCacheConfiguration =>
 自动配置了RedisCacheManager =>  初始化所有的缓存 => 
 每个缓存决定使用什么配置=>
 =>如果RredisCacheConfiguration有就用已有的,没有就用默认配置(CacheProperties)
 =>想改缓存的配置,只要给容器中放一个RredisCacheConfiguration即可
 =>就会应用到当前RedisCacheManager管理的所有缓存分区中
 

1、CacheAutoConfiguration 

缓存的自动配置,用的类型是redis所以看 RedisCacheConfiguration

2、CacheManager

缓存管理者,类型是redis所以看 RedisCacheManager

3、CacheProperties 

缓存默认配置

三、常用注解

1、@CacheConfig

在类级别共享缓存的相同配置。如果一个类中,多个方法都有同样的 cacheName,keyGenerator,cacheManager 和 cacheResolver,可以直接使用 @CacheConfig 注解在类上声明,这个类中的方法都会使用@CacheConfig 属性设置的相关配置。

@Component
@CacheConfig(cacheNames = "mall_cache")
public class CacheComponent {@Cacheable(key = "'perm-whitelist-'+#clientId", unless="#result == null")public List<String> cacheWriteList(String clientId){...}@Cacheable(key = "'perm-cutom-aci-' + #tenantId + '-' + #roleId + '-' + #tenantLevel + '-' + #subType", unless="#result == null")public List<RequestDto> cacheRequest(Long tenantId,Long roleId,Integer tenantLevel,Integer subType){...}
}
2、@Cacheable

触发将数据保存到缓存的操作(启动缓存),有9给属性:value、 cacheNames、 key、 keyGenerator、 cacheManager、 cacheResolver、 condition、 unless、 sync。

2.1、value/cacheNames 属性

这两个属性代表的意义相同,根据@AliasFor注解就能看出来了。这两个属性都是用来指定缓存组件的名称,即将方法的返回结果放在哪个缓存中,属性定义为数组,可以指定多个缓存;

2.2、key

可以通过 key 属性来指定缓存数据所使用的的 key,默认使用的是方法调用传过来的参数作为 key。最终缓存中存储的内容格式为:Entry<key,value> 形式。

(1)如果请求没有参数:key=new SimpleKey();

(2)如果请求有一个参数:key=参数的值

(3)如果请求有多个参数:key=newSimpleKey(params); (你只要知道 key不会为空就行了)

key的实现有两种方式:

(1) SpEL 表达式

(2)使用 keyGenerator生成器的方式来指定 key,需要编写一个 keyGenerator ,将该生成器注册到 IOC 容器即可。

2.3、keyGenerator 

key 的生成器。如果觉得通过参数的方式来指定比较麻烦,我们可以自己指定 key 的生成器的组件 id。key/keyGenerator属性:二选一使用。

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.Arrays;@Configuration
public class MyCacheConfig {@Bean("myKeyGenerator")public KeyGenerator keyGenerator(){return new KeyGenerator(){@Overridepublic Object generate(Object target, Method method, Object... params) {return method.getName()+ Arrays.asList(params).toString();}};}/*** 支持 lambda 表达式编写*//*@Bean("myKeyGenerator")public KeyGenerator keyGenerator(){return ( target,  method, params)-> method.getName()+ Arrays.asList(params).toString();}*/
}
2.4、cacheManager  

用来指定缓存管理器。针对不同的缓存技术,需要实现不同的 cacheManager,Spring 也为我们定义了如下的一些 cacheManger 实现()

2.5、cacheResolver 

该属性,用来指定缓存解析器。使用配置同 cacheManager 类似(cacheManager指定管理器/cacheResolver指定解析器 它俩也是二选一使用) 

2.6、condition 

条件判断属性,用来指定符合指定的条件下才可以缓存。也可以通过 SpEL 表达式进行设置。这个配置规则和上面表格中的配置规则是相同的。

@Cacheable(value = "user",condition = "#id>0")//传入的 id 参数值>0才进行缓存
User getUser(Integer id);@Cacheable(value = "user",condition = "#a0>1")//传入的第一个参数的值>1的时候才进行缓存
User getUser(Integer id);@Cacheable(value = "user",condition = "#a0>1 and #root.methodName eq 'getUser'")//传入的第一个参数的值>1 且 方法名为 getUser 的时候才进行缓存
User getUser(Integer id);
2.7、unless  

unless属性,意为"除非"的意思。即只有 unless 指定的条件为 true 时,方法的返回值才不会被缓存。可以在获取到结果后进行判断。

@Cacheable(value = "user",unless = "#result == null")//当方法返回值为 null 时,就不缓存
User getUser(Integer id);@Cacheable(value = "user",unless = "#a0 == 1")//如果第一个参数的值是1,结果不缓存
User getUser(Integer id);
2.8、sync

该属性用来指定是否使用异步模式,该属性默认值为 false,默认为同步模式。异步模式指定 sync = true 即可,异步模式下 unless 属性不可用。 

3、@CacheEvict

触发将数据从缓存删除的操纵(失效模式)。@CacheEvict 是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。属性有下面几个:

public @interface CacheEvict {@AliasFor("cacheNames")String[] value() default {};@AliasFor("value")String[] cacheNames() default {};String key() default "";String keyGenerator() default "";String cacheManager() default "";String cacheResolver() default "";String condition() default "";boolean allEntries() default false;boolean beforeInvocation() default false;
}

其他的几个和@Cacheable的属性差不多,这里看下上面没有介绍过的:
​(1)allEntries:是否需要清除缓存中的所有元素。默认为 false ,表示不需要。当指定了 allEntries 为 true 时,Spring Cache将忽略指定的key,删除缓存中所有键;被注解的方法抛异常也能执行。
​ (2)beforeInvocation: 是否在方法执行成功之后触发键删除操作,默认是在对应方法成功执行之后触发的,若此时方法抛出异常而未能成功返回,不会触发清除操作。指定该属性值为 true 时,Spring会在调用该方法之前清除缓存中的指定元素。

4、@CachePut

不影响方法执行更新缓存(双写模式)。

5、@Caching

组合以上多个操作(点击注解看源码就知道了,组合注解))。

public @interface Caching {Cacheable[] cacheable() default {};CachePut[] put() default {};CacheEvict[] evict() default {};
}

@Caching 注解可以在一个方法或者类上同时指定多个Spring Cache相关的注解。
其拥有三个属性:cacheable、put 和 evict,分别用于指定@Cacheable、@CachePut 和 @CacheEvict。对于一个数据变动,更新多个缓存的场景,可以通过 @Caching 来实现:

@Caching(cacheable = @Cacheable(cacheNames = "caching", key = "#age"), evict = @CacheEvict(cacheNames = "t4", key = "#age"))
public String caching(int age) {return "caching: " + age + "-->" + UUID.randomUUID().toString();
}

上面这个就是组合操作:从 caching::#age 缓存取数据,不存在时执行方法并写入缓存;删除缓存 t4::#age。


http://www.ppmy.cn/server/25000.html

相关文章

动态规划:0/1背包问题

01背包问题是一个经典的动态规划问题&#xff0c;它询问在给定的物品和背包容量下&#xff0c;如何选择物品使得背包中的物品总价值最大&#xff0c;同时保证不超过背包的容量限制。物品不能分割&#xff0c;每个物品只能选择放入或不放入背包。 问题定义 输入&#xff1a; 物…

HarmonyOS-Next开源三方库 MPChart:打造出色的图表体验

点击下载源码https://download.csdn.net/download/liuhaikang/89228765 简介 随着移动应用的不断发展&#xff0c;数据可视化成为提高用户体验和数据交流的重要手段之一。在 OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&#xff09;应用开发中&#xff0c;一个强大而…

大语言模型在专业领域的应用——医疗场景下的大语言模型

大语言模型在专业领域的应用——医疗场景下的大语言模型 构建面向医疗的大语言模型数据资源总结医疗是与人类生活密切相关的重要领域之一。由于具有较强的通用任务解决能力,大语言模型被广泛用于辅助医生处理各种相关医疗任务,例如医疗诊断、临床报告生成、医学语言翻译、心理…

编译工具各版本与操作系统版本号兼容性冷知识 : JetBrains IntelliJ IDEA 各个主要版本及其对应的操作系统版本号的兼容情况

编译工具各版本与操作系统版本号兼容性冷知识 &#x1f9e0;: JetBrains IntelliJ IDEA 各个主要版本及其对应的操作系统版本号的兼容情况 文章目录 编译工具各版本与操作系统版本号兼容性冷知识 &#x1f9e0;: JetBrains IntelliJ IDEA 各个主要版本及其对应的操作系统版本号…

站群SEO优化策略及其遭遇DDoS攻击时的应对方法

一、站群SEO优化策略 站群优化主要是指通过合理布局和内容优化提升一系列网站在搜索引擎中的整体排名表现。以下是一些关键步骤与相关代码示例&#xff08;以WordPress为例&#xff09;&#xff1a; 差异化内容建设&#xff1a; 每个站点的内容必须具有独立性和价值性&#x…

asyncio异步编程(三)

1.异步迭代器 迭代器&#xff1a;内部实现__iter__()和__next__()方法的对象。 可迭代对象&#xff1a;内部实现__iter__()方法&#xff0c;并且可以返回迭代器的对象。 异步迭代器&#xff1a;实现__aiter__()和__anext__()方法的对象。 异步可迭代对象&#xff1a;内部实…

未来已来:深入探索LLAMA3驱动的人工智能革命

大家好&#xff01;相信大家对于AI&#xff08;人工智能&#xff09;的发展已经有了一定的了解&#xff0c;但你是否意识到&#xff0c;到了2024年&#xff0c;AI已经变得如此强大和普及&#xff0c;带来了我们从未想象过的便利和创新呢&#xff1f;让我们一起来看看AI在这个时…

http基础了解

超文本传输协议&#xff08;HTTP&#xff09;是一个用于传输超媒体文档&#xff08;例如 HTML&#xff09;的应用层协议。它是为 Web 浏览器与 Web 服务器之间的通信而设计的&#xff0c;但也可以用于其他目的。HTTP 遵循经典的客户端—服务端模型&#xff0c;客户端打开一个连…

pytorch-解决过拟合之动量与学习率衰减

目录 1. momentum动量2. pytorch增加momentum3. 学习率衰减4. 学习率衰减的方式4.1 loss连续几次无改善衰减 4.2 步进式衰减 1. momentum动量 下图给出了梯度公式和增加了动量的梯度公式&#xff0c;β z k z^k zk其中的 z k z^k zk就是上次的梯度&#xff0c;而β决定了 w k …

【React】反向代理和修改打包后的目录

反向代理 前提是做了反向代理&#xff1a; 安装 http-proxy-middleware npm i http-proxy-middleware在src/下新建 setupProxy.js const proxy require("http-proxy-middleware");module.exports function(app) {app.use(proxy("/api", {target: &qu…

Sublime Vim模式配置:q关闭当前标签页

在Sublime安装目录下的->Packages文件夹下新建User文件夹创建文件Vintage.sublime-commands 路径为Sublime安装目录->Packages->User->Vintage.sublime-commands文件内容如下[{"caption": ":w - Save","command": "save"}…

java中的代理模式

静态代理 public interface SmsService {void sent(String message); } class SmsServiceImpl implements SmsService{Overridepublic void sent(String message) {System.out.println("这是发送的信息:"message);} } class SmsServiceProxy implements SmsService{…

边OTG边充电芯片LDR6500

随着科技的飞速发展&#xff0c;智能移动设备已成为我们生活中不可或缺的一部分。而在这些设备的连接与数据传输中&#xff0c;Type-C接口以其高效、便捷的特性逐渐占据了主导地位。OTG&#xff08;On-The-Go&#xff09;技术则进一步扩展了Type-C接口的功能&#xff0c;使得设…

Linux 解压报错

在linux上面解压压缩包&#xff0c;有可能遇到一下问题&#xff0c;现提供正确语句供参考 一、tar命令解压.zip文件 在使用tar命令解压.zip格式文件时&#xff0c;有时会遇到一下异常 gzip: stdin has more than one entry--rest ignored tar: Child returned status 2 ta…

人脸识别系统

一、引言 随着科技的飞速发展,人脸识别技术已经成为现代社会中一个重要的科技应用领域。人脸识别系统,顾名思义,是通过分析人的面部特征进行身份识别的一种技术。近年来,这一技术在公共安全、金融服务、智能门禁、手机解锁等多个领域得到了广泛应用,极大地提升了社会的安…

【NTN 卫星通信】NTN应该使用FDD还是TDD双工模式

1 概述 现在主流的商用地面通信系统一般都支持FDD和TDD两种模式&#xff0c;实用于不同的频段。那么卫星通信也需要有这两种模式吗&#xff1f; 2 NTN 双工模式分析 在考虑TDD模式时&#xff0c;需要设置保护时间&#xff0c;以防止终端同时发射和接收。该保护时间直接取决于终…

Kafka 3.x.x 入门到精通(06)——Kafka进阶

Kafka 3.x.x 入门到精通&#xff08;06&#xff09;&#x1f449;&#x1f449;&#x1f449;&#x1f449; Kafka进阶 3. Kafka进阶3.1 Controller选举3.2 Broker上线下线3.3 数据偏移量定位3.4 Topic删除3.5 日志清理和压缩3.7 页缓存3.8 零拷贝3.9 顺写日志3.10 Linux集群部…

webpack中mode、NODE_ENV、DefinePlugin、cross-env的使用

本文讲的全部知识点&#xff0c;都是和webpack相关的。如果你之前有疑问&#xff0c;那本文一定能帮你搞清楚。 问题来源一般是类似下面代码&#xff08;webpack.json中&#xff09;&#xff1a; "scripts": {"dev": "cross-env NODE_ENVdevelopmen…

Agent AI智能体:未来社会的无形引领者

目录 前言1. 智能体说明1.1 定义1.2 作用1.3 类型介绍1.4 核心技术 2. 技术进步与创新2.1 机器学习的进步2.2 深度学习与神经网络2.3 强化学习2.4 转移学习与多任务学习2.5 自然语言处理(NLP)的革新2.6 知识图谱与推理 3. 行业领域应用场景3.1 游戏行业3.2 医疗健康3.3 金融服务…

uniapp 自定义 App启动图

由于uniapp默认的启动界面太过普通 所以需要自定义个启动图 普通的图片不可以过不了苹果的审核 所以使用storyboard启动图 生成 storyboard 的网站&#xff1a;初雪云-提供一站式App上传发布解决方案