spring cache @Cacheable的使用

news2024/11/20 0:26:27

@Cacheable的使用

  • 1.@Cacheable
    • 1.1 cacheNames value
    • 1.2 关联多个缓存名
    • 1.3 key 和 keygenerator
    • 1.4 CacheManager CacheResolver
    • 1.5 sync
    • 1.6 condition
    • 1.7 unless
  • 2.@CachePut 放置缓存
  • 3.@CacheEvict 删除缓存
  • 4.测试代码
  • 5.默认缓存和redis缓存
  • 6.过程中的问题

1.@Cacheable

注解在方法上,表明方法的返回结果会缓存。相同的参数对应相同的返回缓存。以后相同的参数进行调用时,并不会执行方法,而是使用返回缓存中的值。

1.1 cacheNames value

@Cacheable提供两个参数来指定缓存名
cacheNames value
调用方法时,检查缓存,如果缓存中有数据,不会执行方法。

@Cacheable("menu")
public Menu findById(String id){}

1.2 关联多个缓存名

可以关联多个缓存名,执行方法时,关联的缓存都会检查,只要其中一个缓存命中,这个缓存的值就会返回。

@Cacheable({"menu","menu2"})
public Menu findById(String id){}

1.3 key 和 keygenerator

一个缓存名对应一个注解方法,但是一个方法传入不同的参数,结果不通,区分用到key。
key可以显示指定,也可以通过keygenerator生成

不指定key则会采用keyGenerator进行自动生成

官方推荐显式的指定key,可以通过springEL表达式来解决不同入参的问题

@Cacheable(value={"menu"},key="#id")
public Menu findById(String id){}

@Cacheable(value={"menu"},key="'id-'+#menu.id")
public Menu findById(Menu menu){}

key和keyGenerator是互斥的,同时指定两个会导致异常

1.4 CacheManager CacheResolver

CacheManager 缓存管理器用来管理一级缓存。缓存管理器与缓存组件类型相关联的。
srping缓存抽象的目的是为使用不同的缓存组件类型提供提供统一的访问接口,以向开发者屏蔽各种缓存组件的差异。
CacheResolver 缓存解析器是用来管理缓存管理器的,CacheResolver保持CacheManager的引用,并用他来检索缓存。类似于keyGenerator和key

一般情况下,系统只会使用一种缓存,不需要显式的指定CacheManager和CacheResolver。同时配置多中缓存,需要指定,使用的是@cacheable中的参数

1.5 sync

是否同步,多线程环境下相同参数的访问是否进行对入口加锁,即只有一个线程计算操作的结果值,避免了n-1次数据库访问
sync=true 可以有效避免缓存击穿的问题

1.6 condition

调用前判断,缓存的条件。接受springEL表达式,为true进行缓存,否则直接调用

1.7 unless

springEL表达式,为ture不缓存,为false缓存

2.@CachePut 放置缓存

@CachePut和@Cacheable属性相同
@CachePut是执行方法体缓存结果
@Cacheable是查找缓存,有就返回,没有执行方法体,缓存结果

3.@CacheEvict 删除缓存

  • beforeInvocation 是否在方法执行前清除缓存 默认false
    true的时候,先删除缓存,删除数据失败,查询会直达数据库,造成压力;
    false,先删除数据库,删除缓存失败,会造成脏缓存。多线程,执行缓存删除,方法执行慢,此时其他线程获得了脏缓存
  • allEntries 是否删除整个缓存(value和cacheNames指定的)

4.测试代码

依赖

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

配置

spring.redis.host=127.0.0.1
spring.redis.password=123456
spring.redis.port=6379

启动类注解

@SpringBootApplication
@EnableCaching
public class RedisTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisTestApplication.class, args);
    }

}

请求入口

@RestController
public class CacheTestController {

    @Autowired
    private CacheTest cacheTest;

    @RequestMapping("putCache")
    public String testCachePut(){
        cacheTest.testCachePut();
        return "放置缓存成功";
    }

    @RequestMapping("testCacheable")
    public String testCacheable(){
        cacheTest.testCacheable();
        return "获取缓存";
    }

    @RequestMapping("deleteCache")
    public String testCacheEvict(){
        cacheTest.testCacheEvict();
        return  "删除缓存";
    }
}	

缓存

@Component
public class CacheTest {


    @Autowired
    CacheManager cacheManager;



    @CachePut(value = "test1",key = "'testCache1'")
    public Integer testCachePut(){
        System.out.println("放置缓存");
        return 1;
    }

    @Cacheable(value = "test1",key = "'testCache1'")
    public Integer testCacheable(){
        System.out.println("缓存测试");
        return 1;
    }

    @CacheEvict(value = "test1",key = "'testCache1'")
    public void testCacheEvict(){
        System.out.println("删除缓存");
        return ;
    }

    public void getCache(){
//        System.out.println(redisCacheManager.getCache("test1"));
        System.out.println(cacheManager.getCache("test1"));
    }
}

在这里插入图片描述

在进行请求后会发现redis中多了对应key的数据

在这里插入图片描述

在删除缓存后进行获取缓存测试,会发现,在没有缓存的时候会执行一次方法,之后多次调用就不会调用方法,而是获取缓存。
在这里插入图片描述

删除缓存后刷新redis,已经找不到对应key的数据了

5.默认缓存和redis缓存

不引入redis依赖 使用的是spring的缓存
CacheManager在没有redis依赖时,getCache走的ConcurrentMapCacheManager类中的
拿到的cache对象为org.springframework.cache.concurrent.ConcurrentMapCache@8347d73
有redis依赖getCache走的是AbstractCacheManager类中的
拿到的cache对象为org.springframework.data.redis.cache.RedisCache@11e1d8da

默认缓存的生命周期和项目周期是一致的。
redis缓存的生命周期是和redis中的数据的生命周期是一致的。
项目发版(重启)默认缓存会丢失,但是redis缓存,只要redis数据没清除,就不需要重新获取缓存。
为什么要用redis做缓存?
1.redis可以用几十G的内存来做缓存
2.redis缓存可以持久化
3.redis是分布式缓存,默认缓存的生命周期随着jvm的销毁而结束,属于本地缓存,不具有一致性。
4.redis可以处理百万并发,专业的缓存服务
5.redis缓存有过期机制
6.redis有丰富的API

6.过程中的问题

  • 1.起初一直没有在redis中找到对应key的缓存
    发现引入依赖spring-boot-starter-data-redis解决,将相应的redis相关bean扫入spring容器
  • 2.在公司测试好使,回家复现发现缓存不生效,@Cacheable不生效
    在启动类中加入 @EnableCaching解决,并不是网上的那些引入什么aop依赖,通过@EnableCaching注解中的@import注解注入代理的相关类。奇怪的是公司项目的启动类中并没有。初步怀疑是spring版本的问题,等知道了回来补上答案

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

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

相关文章

剩余系,欧拉定理,扩展欧拉定理

剩余类&#xff08;同余类&#xff09; 给定一个正整数n&#xff0c;以 r ∈[0, n -1]表示所有形如的整数组成的集合称为模n的剩余类。例n 5,r 3,则C3 5x &#xff0b;3为模5的一个剩余类。 完全剩余系&#xff08;完系&#xff09; 给定一个正整数n&#xff0c;在模n的剩…

kafka生产者API

生产者工作流程 首先生产者调用send方法发送消息后&#xff0c;会先经过拦截器&#xff0c;接着进入序列化器。序列化器主要用于对消息的Key和Value进行序列化。接着进入分区器选择消息的分区。 上面这几步完成之后&#xff0c;消息会进入到一个名为RecordAccumulator的缓冲队…

javaWeb servlet

使用案例&#xff1a; <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> 导了包之…

五指山[《信息学奥赛一本通》](扩展欧几里得算法)

题目如下&#xff1a; 题解 or 思路 我们可以将题目 抽象 成数学模型 xkd≡y(modn)x kd \equiv y\ (mod\ n)xkd≡y (mod n) xkdya∗nx kd y a * nxkdya∗n k∗d−a∗ny−xk*d - a*n y - xk∗d−a∗ny−x 式子 在这里 kkk, aaa 是变量&#xff0c;其余是常数 我们可以扩展…

Java 快速开发几 MB 独立 EXE,写图形界面很方便

Java 写的桌面软件带上运行时只有 6 MB&#xff0c;而且还是独立 EXE 文 件&#xff0c;是不是难以置信&#xff1f; 想一想 Electron 没写多少功能就可能超过百 MB 的体积&#xff0c;Java 写的桌面软件算不算得上小、轻、快呢&#xff1f; aardio 可以支持很多编程语言&…

什么是 智慧行业 App?

智慧行业 是帮助大家将智能设备和边缘网关设备添加到云开发项目的移动端 App。App 提供 iOS 和安卓版本&#xff0c;您可以在对应系统的应用商店下载。 应用场景 智慧行业 能帮助用户将不同网络协议的设备&#xff08;包含边缘网关子设备&#xff09;配置到相关项目中。开发者…

对于TP, TN, FP, FN, Pre, Recall的举例

对于以上参数的概念以及理解&#xff0c;请参考我的文章&#xff1a; 机器学习中TP&#xff0c;TN&#xff0c;FP&#xff0c;FN&#xff0c;Acc&#xff0c;Pre&#xff0c;Sen, Rec的含义_汤宪宇的博客-CSDN博客_机器学习accz 这里我们在将上面概念的定义重新梳理一遍&#…

深入源码剖析 Mybatis 缓存机制

深入源码剖析 Mybatis 缓存机制 Mybatis 为了减轻数据库压力&#xff0c;提高数据库性能。提供了两级缓存机制 一级缓存 sqlSession 级别缓存&#xff0c;缓存的数据只在 sqlSession 内有效&#xff0c;一级缓存默认为我们开起来&#xff0c;不需要我们手动操作&#xff0c;而…

【Dash搭建可视化网站】项目14:美国机场交通数据可视化看板制作步骤详解

美国机场交通数据可视化看板制作步骤详解1 项目效果图2 项目架构3 文件介绍和功能完善3.1 assets文件夹介绍3.2 app.py和index.py文件完善3.3 sider.py文件完善3.4 mapchart.py文件完善3.5 barchart.py文件完善3.6 api.py和api.ipynb文件完善4 样式修改4.1 整体样式修改4.2 sid…

联合证券|A股汽车板块爆发,北向资金半日净买入43亿

今日上午&#xff0c;A股商场震动胶着&#xff0c;轿车、电力设备、通信、机械设备等板块领涨。房地产、美容护理、商贸零售等板块领跌。 北向资金再度成为商场重要亮点之一&#xff0c;半个交易日净买入约43亿元。至此&#xff0c;2023年1月以来&#xff0c;北向资金累计净买入…

Jmeter常用函数

1、生成随机数函数 ${__Random(m,n)}&#xff0c;其中m,n参数是必填 2、 生成随机日期函数${__RandomDate(dateTimeFormat,from,end,locale,var)}&#xff0c;其中end是必选的&#xff0c;代表最大的日期&#xff1b; 3、 随机生成字符串函数${__RandomString(length,chars,)}…

Linux---vim编辑器

目录 1. vim的基本概念 2. vim正常/命令模式命令集 3. vim底行模式命令集 1. vim的基本概念 vim是Linux下一款常用编辑器&#xff0c;vim的三种模式(其实有好多模式&#xff0c;主要掌握这3种即可),分别是命令模式&#xff08;command mode&#xff09;、插入模式&#xff0…

Synchronized锁原理及 ConcurrentHashMap

文章目录一、Synchronized原理加锁过程锁消除锁粗化二、线程安全的集合类多线程环境使用ArrayList多线程环境使用队列多线程环境下使用哈希表一、Synchronized原理 我们表面看到的&#xff0c;两个线程针对同一对象加锁&#xff0c;就会产生阻塞等待&#xff0c;但实际我们的S…

2023我的创作纪念日

文章目录机缘收获日常憧憬机缘 这个博客还是我上大一的时候注册的&#xff0c;在大一、大二、大三期间更多的是为了方便搜索&#xff0c;学校里边的习题大部分是可以在CSDN上找到的。真正写博客是在大三下学习实习&#xff0c;当时为了方便记录实习中遇到的问题。在C站对我影响…

【Git 从入门到精通】2023最新版的Git安装与卸载每一步附详细讲解

文章目录安装1.下载Git2.开始安装卸载1.找到电脑中的Git2.卸载3.删除环境变量安装 1.下载Git 首先去官网下载Git安装包&#xff0c;可以直接在百度搜索Git&#xff0c;以下几个网站都可以。也可以点击直达&#xff0c;官网上下载如果不科学上网的话还是很慢的&#xff0c;所以…

[Zombodb那些事]Zombodb与ElasticSearch的Bulk通信

Zombodb与ElasticSearch的Bulk通信0.前言Zombodb是一个PostgreSQL插件&#xff0c;使用rust编写&#xff0c;支持pg14以下版本。Zombodb可以允许PostgreSQL查询ElasticSearch中的内容。本篇为《Zombodb那些事》第一篇&#xff0c;后面将更新其他部分内容。Zombodb会在pg数据库上…

智能文字识别技术推动彝文识别弘扬中华文化

前言 谈起图像识别自己颇有感触&#xff0c;因为之前的两段工作经历都和图像识别密切相关&#xff1b;之前一家公司的主营业务就是将历史上珍贵文献进行数字化&#xff1b;上家公司自己负责图像识别模块相关的工作&#xff1b;不但使用了第三方平台产品而且进行了自建&#xff…

设计模式相关内容介绍—UML

统一建模语言(Unified ModelingLanguage&#xff0c;UML)是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。 UML从目标系统的不同角度出发&#xff0c;定义了用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图、…

经过2022年这大环境,我学会了如何管理我的领导

2022年这大环境&#xff0c;可以说是我干软件开发这些年来&#xff0c;经历的最残酷的一年&#xff0c;所以做为职场软件开发一员的我&#xff0c;不得不修炼一下真本事。 很多时候不是你不努力&#xff0c;不是你连mysql连的不溜&#xff0c;不是你布局页面布局的不精细&#…

16.Isaac教程--Codelets详解

Codelets详解 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录Codelets详解Codelets 和 tick接收消息传输消息方便的 ToProto/FromProto 函数配置参数应用程序 JSON子图姿态组件是机器人应用程序的基本构建块。 Isaac SDK 包含可在您的应…