spring cache(一)介绍

news2024/11/18 3:47:31

一、介绍

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(){

            @Override
            public 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.coloradmin.cn/o/1625094.html

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

相关文章

MySql基础一之【了解MySql与DBeaver操作MySql】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言MySQL的基本介绍DBeaver及MYSQL操作 前言 本系列为MySql基础&#xff0c…

抽象工厂模式(Redis 集群升级)

目录 定义 Redis 集群升级 模拟单机服务 RedisUtils 模拟集群 EGM 模拟集群 IIR 定义使⽤接⼝ 实现调⽤代码 代码实现 定义适配接⼝ 实现集群使⽤服务 EGMCacheAdapter IIRCacheAdapter 定义抽象⼯程代理类和实现 JDKProxy JDKInvocationHandler 测试验证 定义 …

2024最新版JavaScript逆向爬虫教程-------基础篇之面向对象

目录 一、概念二、对象的创建和操作2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承3.3.1 对象的原型式继承3.3.2 …

Docker——开源的应用容器的引擎

目录 一、前言 1.虚拟化产品有哪些 1.1寄居架构 1.2源生架构 2.虚拟化产品对比/介绍 2.1虚拟化产品 2.1.1仿真虚拟化 2.1.2半虚拟化 2.1.3全虚拟化 2.2重点 2.2.1KVM——Linux内核来完成的功能和性能 2.2.2ESXI——用的比较多 二、Docker概述 1.Docker定义 2.Do…

Docker容器:网络模式与资源控制

目录 一、Docker 网络模式 1、Docker 网络实现原理 2、Docker 网络模式概述 2.1 Host 模式 2.2 Container 模式 2.3 None 模式 2.4 Bridge 模式 2.5 自定义网络&#xff08;user-defined network&#xff09; 3、配置 docker 网络模式 3.1 查看网络基础命令 3.1.1 查…

Git操作与异常处理

文章目录 常用操作1、代码拉取2、代码提交3、暂存区状态4、提交代码5、推送远程仓库 异常处理【1】报错信息&#xff1a;Cannot pull into a repository with state: MERGING【2】报错信息&#xff1a;You have not concluded your merge (MERGE_HEAD exists)【3】报错信息&…

PM2管理器无法使用解决方法

之前的项目全是依靠PM2管理器部署的&#xff0c;部署快速&#xff0c;也便于管理 但是宝塔实在是bug毛病太多&#xff0c;最近这两天又出毛病了 这次的问题是在PM2管理器的node版本中无法进行版本切换&#xff0c;如果是第一次使用PM2的话甚至无法设置node版本&#xff0c;之前…

陪丨玩丨系丨统搭建制作流程APP小程序H5多端源码前后端一次性交付,本地授权,无二次费用!可定制开发!

陪丨玩app小程序H5开发&#xff0c;软件搭建&#xff0c;程序制作、系统设计 数据存储是陪玩平台源码的重点&#xff0c;没有数据库&#xff0c;用户的账号信息、平台产生的数据都无法顺利存储和读取&#xff0c;不能让用户拥有完善良好的用户体验。虽然是存放在服务器上&…

体验馆设计要考虑哪些需求

1、和谐 许多人认为&#xff0c;在所有规律中&#xff0c;和谐是体验馆设计最重要的一条规律。体验馆是由很多因素&#xff0c;包括布局、照明、色彩、图表、展品、展架、展具等组成。一个好的体验馆&#xff0c;须融合着所有的元素。 但万事都有一个度的把握&#xff0c;过于完…

Linux论坛搭建

1.安装httpd服务 1.1安装httpd软件 [rootlocalhost yum.repos.d]# dnf install httpd 1.2.修改httpd的配置 [rootlocalhost yum.repos.d]# vim /etc/httpd/conf/httpd.conf 1.3.启动这个httpd服务,并查看它的状态 [rootlocalhost yum.repos.d]# systemctl start httpd [ro…

LabVIEW多通道数据采集系统

LabVIEW多通道数据采集系统 在当今的数据采集领域&#xff0c;随着技术的不断进步和应用需求的日益增长&#xff0c;对数据采集系统的速度、稳定性和灵活性要求也越来越高。基于千兆以太网和LabVIEW的多通道数据采集系统&#xff0c;以其高速的数据传输能力和强大的数据处理功…

MySQL中什么情况下会出现索引失效?如何排查索引失效?

目录 1-引言&#xff1a;什么是MySQL的索引失效&#xff1f;(What、Why)1-1 索引失效定义1-2 为什么排查索引失效 2- 索引失效的原因及排查&#xff08;How&#xff09;2-1 索引失效的情况① 索引列参与计算② 对索引列进行函数操作③ 查询中使用了 OR 两边有范围查询 > 或 …

自动雷达水位雨量监测系统的组成

TH-SW2随着科技的不断发展&#xff0c;自动雷达水位雨量监测系统成为了现代气象和水文观测的重要工具。该系统结合了雷达技术与自动化控制技术&#xff0c;为气象、水文、环境等领域提供了实时、准确的数据支持。下面&#xff0c;我们将详细介绍自动雷达水位雨量监测系统的组成…

使用R语言进行简单的主成分分析(PCA)

主成分分析&#xff08;PCA&#xff09;是一种广泛使用的数据降维技术&#xff0c;它可以帮助我们识别数据中最重要的特征并简化复杂度&#xff0c;同时尽量保留原始数据的关键信息。在这篇文章中&#xff0c;我们将通过一个具体的例子&#xff0c;使用R语言实现PCA&#xff0c…

零门槛接入,开源的物联网超级中枢:ThingsBoard

ThingsBoard&#xff1a;重塑万物互联世界&#xff0c;无限可能拓展- 精选真开源&#xff0c;释放新价值。 概览 ThingsBoard是一款强大而灵活的开源物联网&#xff08;IoT&#xff09;平台&#xff0c;以其高度可扩展性和企业级功能赢得了全球开发者与企业的青睐。它无缝集成…

主机电源相关测试脚本:ping通 - 停止唤醒

简介&#xff1a;在进行一些涉及服务器或者PC主机的电源关机、开机、重启相关的测试中&#xff0c;远程开机或者唤醒&#xff0c;结合pythonping模块处理ping&#xff0c;可以节省出不必要的硬性等待时间&#xff0c;规避开机时间不稳定的情况&#xff0c;而且不会造成堵塞现象…

(一)Dataframes安装与类型 #Julia数据分析 #CDA学习打卡

目录 一. Julia简介 二. Dataframe构造方法 1&#xff09;访问列的方式 &#xff08;a&#xff09;判断严格相等 i. 切片严格相等是true ii. 复制严格相等是false &#xff08;b&#xff09;判断相等 i. 切片相等是true ii. 复制相等是true 2&#xff09;获取列名称 …

LORA详解

参考论文&#xff1a; low rank adaption of llm 背景介绍&#xff1a; 自然语言处理的一个重要范式包括对一般领域数据的大规模预训练和对特定任务或领域的适应处理。在自然语言处理中的许多应用依赖于将一个大规模的预训练语言模型适配到多个下游应用上。这种适配通常是通过…

unity学习(91)——云服务器调试——补充catch和if判断

本机局域网没问题&#xff0c;服务器放入云服务器后&#xff0c;会出现异常。 想要找到上面的问题&#xff0c;最简单的方法就是在云服务器上下载一个vs2022&#xff01; 应该不是大小端的问题&#xff01; 修改一下readMessage的内容&#xff0c;可以直接粘贴到云服务器的。 …

【Python系列】字符串操作

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…