SpringBoot系列缓存注解@Cacheable @CacheEvit @CachePut使用姿势介绍

Spring在3.1版本,就提供了一条基于注解的缓存策略,实际使用起来还是很丝滑的,本文将针对几个常用的注解进行简单的介绍说明,有需要的小伙伴可以尝试一下

本文主要知识点:

  • @Cacheable: 缓存存在,则使用缓存;不存在,则执行方法,并将结果塞入缓存
  • @CacheEvit: 失效缓存
  • @CachePut: 更新缓存

I. 项目环境

1. 项目依赖

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA + redis5.0进行开发

开一个web服务用于测试

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

全程使用默认配置,redis本机,端口6379,无密码

II. 缓存注解介绍

1. @Cacheable

这个注解用于修饰方法or类,当我们访问它修饰的方法时,优先从缓存中获取,若缓存中存在,则直接获取缓存的值;缓存不存在时,执行方法,并将结果写入缓存

这个注解,有两个比较核心的设置

 /*** 与 cacheNames 效果等价*/@AliasFor("cacheNames")String[] value() default {};@AliasFor("value")String[] cacheNames() default {};/*** 缓存key*/String key() default "";

cacheNames可以理解为缓存key的前缀,可以为组件缓存的key变量;当key不设置时,使用方法参数来初始化,注意key为SpEL表达式,因此如果要写字符串时,用单引号括起来

一个简单的使用姿势

/*** 首先从缓存中查,查到之后,直接返回缓存数据;否则执行方法,并将结果缓存* <p>* redisKey: cacheNames + key 组合而成 --> 支持SpEL* redisValue: 返回结果** @param name* @return*/
@Cacheable(cacheNames = "say", key = "'p_'+ #name")
public String sayHello(String name) {return "hello+" + name + "-->" + UUID.randomUUID().toString();
}

如我们传参为 yihuihui, 那么缓存key为 say::p_yihuihui

除了上面三个配置值之外,查看@Cacheable注解源码的童鞋可以看到还有condition设置,这个表示当它设置的条件达成时,才写入缓存

/*** 满足condition条件的才写入缓存** @param age* @return*/
@Cacheable(cacheNames = "condition", key = "#age", condition = "#age % 2 == 0")
public String setByCondition(int age) {return "condition:" + age + "-->" + UUID.randomUUID().toString();
}

上面这个case中,age为偶数的时候,才走缓存;否则不写缓存

接下来是unless参数,从名字上可以看出它表示不满足条件时才写入缓存

/*** unless, 不满足条件才写入缓存** @param age* @return*/
@Cacheable(cacheNames = "unless", key = "#age", unless = "#age % 2 == 0")
public String setUnless(int age) {return "unless:" + age + "-->" + UUID.randomUUID().toString();
}

2. @CachePut

不管缓存有没有,都将方法的返回结果写入缓存;适用于缓存更新

/*** 不管缓存有没有,都写入缓存** @param age* @return*/
@CachePut(cacheNames = "t4", key = "#age")
public String cachePut(int age) {return "t4:" + age + "-->" + UUID.randomUUID().toString();
}

3. @CacheEvict

这个就是我们理解的删除缓存

/*** 失效缓存** @param name* @return*/
@CacheEvict(cacheNames = "say", key = "'p_'+ #name")
public String evict(String name) {return "evict+" + name + "-->" + UUID.randomUUID().toString();
}

4. @Caching

在实际的工作中,经常会遇到一个数据变动,更新多个缓存的场景,对于这个场景,可以通过@Caching来实现

/*** caching实现组合,添加缓存,并失效其他的缓存** @param age* @return*/
@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

5. 异常时,缓存会怎样?

上面的几个case,都是正常的场景,当方法抛出异常时,这个缓存表现会怎样?

/*** 用于测试异常时,是否会写入缓存** @param age* @return*/
@Cacheable(cacheNames = "exception", key = "#age")
@Cacheable(cacheNames = "say", key = "'p_yihuihui'")
public int exception(int age) {return 10 / age;
}

根据实测结果,当age==0时,上面两个缓存都不会成功

6. 测试用例

接下来验证下缓存注解与上面描述的是否一致

@RestController
public class IndexRest {@Autowiredprivate BasicDemo helloService;@GetMapping(path = {"", "/"})public String hello(String name) {return helloService.sayHello(name);}
}

上面这个主要是验证@Cacheable注解,若缓存不命中,每次返回的结果应该都不一样,然而实际访问时,会发现返回的都是相同的

curl http://localhost:8080/?name=yihuihui

失效缓存

@GetMapping(path = "evict")
public String evict(String name) {return helloService.evict(String.valueOf(name));
}

失效缓存,需要和上面的case配合起来使用

curl http://localhost:8080/evict?name=yihuihui
curl http://localhost:8080/?name=yihuihui

剩下其他的相关测试类就比较好理解了,一并贴出对应的代码

@GetMapping(path = "condition")
public String t1(int age) {return helloService.setByCondition(age);
}@GetMapping(path = "unless")
public String t2(int age) {return helloService.setUnless(age);
}@GetMapping(path = "exception")
public String exception(int age) {try {return String.valueOf(helloService.exception(age));} catch (Exception e) {return e.getMessage();}
}@GetMapping(path = "cachePut")
public String cachePut(int age) {return helloService.cachePut(age);
}

7. 小结

最后管理小结一下Spring提供的几个缓存注解

  • @Cacheable: 缓存存在,则从缓存取;否则执行方法,并将返回结果写入缓存
  • @CacheEvit: 失效缓存
  • @CachePut: 更新缓存
  • @Caching: 都注解组合

上面虽说可以满足常见的缓存使用场景,但是有一个非常重要的点没有说明,缓存失效时间应该怎么设置???

如何给每个缓存设置不同的缓存失效时间,咱么下篇博文见,我是一灰灰,欢迎关注长草的公众号一灰灰blog

III. 不能错过的源码和相关知识点

0. 项目

  • 工程:https://github.com/liuyueyi/spring-boot-demo
  • 源码:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/125-cache-ano

1. 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

  • 一灰灰Blog个人博客 https://blog.hhui.top
  • 一灰灰Blog-Spring专题博客 http://spring.hhui.top

Spring系列缓存注解@Cacheable @CacheEvit @CachePut 使用姿势介绍相关推荐

  1. Spring Boot缓存注解@Cacheable、@CacheEvict、@CachePut使用

    https://blog.csdn.net/dreamhai/article/details/80642010

  2. 三十七、缓存注解@Cacheable、@CacheEvict、@CachePut详解

    #        缓存注解@Cacheable.@CacheEvict.@CachePut详解 ##一.@Cacheable用法详解 ###1.用在哪里?     用在方法或者类上. ###2.这两种 ...

  3. Spring 缓存注解@Cacheable 在缓存时候 ,出现了第一次进入调用 方法 ,第二次不调用的异常

    Spring 缓存注解@Cacheable 在缓存时候 ,出现了第一次进入调用 方法 ,第二次不调用的异常 参考文章: (1)Spring 缓存注解@Cacheable 在缓存时候 ,出现了第一次进入 ...

  4. spring缓存注解@Cacheable和@CacheEvict,设置过期时间和批量模糊删除

    spring缓存注解@Cacheable和@CacheEvict,设置过期时间和批量模糊删除 配置 CacheManager 类 key前缀配置 RedisCache配置 RedisCache 模糊匹 ...

  5. Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

  6. 详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

    注释介绍 @Cacheable @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 @Cacheable 作用和配置方法 参数 解释 example value 缓 ...

  7. cacheable更新_详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

    注释介绍 @Cacheable @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 @Cacheable 作用和配置方法 参数 解释 example value 缓 ...

  8. 2021-10-12Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

  9. cacheable 表达式_Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

  10. cacheable 表达式_Spring Boot缓存注解@Cacheable、@CacheEvict、@CachePut使用

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

最新文章

  1. 第三章 Java Servlet基础
  2. JSP学习02-config内置对象
  3. python datasets 下载_Python机器学习·微教程
  4. 写给萌新,聊聊你初入职场的那些疑惑~
  5. H.264中IDR帧和I帧区别
  6. IntelliJ IDEA——提交代码到GitHub远程库
  7. python3 web服务器_python3 简单web服务器
  8. legend---六、php脚本变量的生命周期是怎样的
  9. 伺服电机选型时,惯量匹配和惯量比的问题
  10. Excel学习笔记3||逻辑函数AND、OR、NOT、XOR、IF、IFS和查找函数VLOOKUP
  11. [MIT]微积分重点 第四课 指数函数(exponential) 学习笔记
  12. Openerp管理权限的方法
  13. 类似vmlogin浏览器的有哪些?vmlogin,AdsPower,候鸟浏览器等防关联浏览器中同类型软件最强是哪一个?防关联指纹浏览器哪个好?
  14. 《Java并发编程的艺术》读书笔记三
  15. jQuery Color Animate (jQuery 颜色变换动画) 插件
  16. Windows 通过bat脚本启动Eureka,Cassandra和redis-server
  17. cocos2dx之Box2D
  18. 面试中最易被“秒杀”的五种表现
  19. android 友盟微信授权2002,友盟 2002错误
  20. 走进京东 | 中国空间技术研究院青年创新联盟成员莅临参观京东总部

热门文章

  1. 东南亚跨境电商shopee平台有什么选品渠道?
  2. excel 如何批量删除必表中的空白行
  3. java 拼音排序:Collator类
  4. 制作一个简单HTML公司官网网页设计(HTML+CSS)
  5. 多数据源配置MyBatisPlus(十八)
  6. 快速创建ppt中的动画效果图。
  7. Notepad++删除空白行
  8. cad完全卸载教程_如何完全卸载(删除)cad-百度经验
  9. Excel没有密码怎么打开
  10. Word设置封面无页码,摘要罗马数字页码,正文数字页码