Spring Cache @Cacheable @CachePut @CacheEvict 讲解和使用案例

2023-11-19

原文链接:https://blog.csdn.net/lpw_cn/article/details/84642647

 

Spring的缓存管理可谓是相当的方便。与其他功能的风格一致,同样的在需要管理的地方添加一个注解,可以是方法,也可以是类。

使用Spring Cache需要我们做两方面的事:

  • 声明某些方法使用缓存
  • 配置Spring对Cache的支持

和Spring对事务管理的支持一样,Spring对Cache的支持也有基于注解和基于XML配置两种方式。下面我们先来看看基于注解的方式。

 

基于注解的支持

Spring为我们提供了几个注解来支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素。下面我们将来详细介绍一下Spring基于注解对Cache的支持所提供的几个注解。

@Cacheable

@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,至于键的话,Spring又支持两种策略,默认策略和自定义策略,这个稍后会进行说明。需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的。
@Cacheable可以指定三个属性,value、key和condition。

value属性指定Cache名称

value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

@Cacheable("cache1")//Cache是发生在cache1上的
public User find(Integer id) {
    return null;
}
@Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的
public User find(Integer id) {
    return null;
}


使用key属性自定义key

key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,至于默认策略会在后文单独介绍。
自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例。

@Cacheable(value="users", key="#id")
public User find(Integer id) {
    return null;
}
@Cacheable(value="users", key="#p0")
public User find(Integer id) {
    return null;
}
@Cacheable(value="users", key="#user.id")
public User find(User user) {
    return null;
}
@Cacheable(value="users", key="#p0.id")
public User find(User user) {
    return null;
}


除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。

属性名称 描述 示例
methodName 当前方法名 #root.methodName
method 当前方法 #root.method.name
target 当前被调用的对象 #root.target
targetClass 当前被调用的对象的class #root.targetClass
args 当前方法参数组成的数组 #root.args[0]
caches 当前被调用的方法使用的Cache #root.caches[0].name

当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:

@Cacheable(value={"users", "xxx"}, key="caches[1].name")
public User find(User user) {
    return null;
}


condition属性指定发生的条件

有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。

@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
public User find(User user) {
    System.out.println("find user by user " + user);
    return user;
}


@CachePut

在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
@CachePut(“users”)//每次都会执行方法,并将结果存入指定的缓存中

public User find(Integer id) {
    return null;
}


@CacheEvict

@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。
其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);
key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;
condition表示清除操作发生的条件。
下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。

allEntries属性

allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

@CacheEvict(value="users", allEntries=true)
public void delete(Integer id) {
System.out.println("delete user by id: " + id);
}


beforeInvocation属性

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

@CacheEvict(value="users", beforeInvocation=true)
public void delete(Integer id) {
System.out.println("delete user by id: " + id);
}


其实除了使用@CacheEvict清除缓存元素外,当我们使用Ehcache作为实现时,我们也可以配置Ehcache自身的驱除策略,其是通过Ehcache的配置文件来指定的。由于Ehcache不是本文描述的重点,这里就不多赘述了,想了解更多关于Ehcache的信息,请查看我关于Ehcache的专栏。

 

 

 


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Cache @Cacheable @CachePut @CacheEvict 讲解和使用案例 的相关文章

随机推荐

  • Linux-centos

    目录 一 Linux入门概述 1 1概述 1 2 下载地址 1 3 Linux特点 1 4 Linux和Windows区别 二 Linux目录结构 2 1 概览 2 2 树状目录结构 三 VI VIM编辑器 3 1 概述 3 2 测试数据准
  • 链队列的基本操作

    define CRT SECURE NO WARNINGS 链栈 include
  • Scala语言入门

    Scala入门 一 Scala安装 二 类和对象 1 Scala基本数据类型 2 Scala定义类 3 Scala单例对象 4 伴生对象 5 控制抽象 三 简单语法 1 if else 2 循环 3 方法 4 字符串 5 数组 6 集合 四
  • 你这样写代码会被打!

    编译 Python 开发者 伯乐在线 http python jobbole com 89252 所有人 好吧 不是所有人 都知道 python 是一门用途广泛 易读 而且容易入门的编程语言 但同时 python 语法也允许我们做一些很奇怪
  • 实现物联网,你有使用合适的数据库吗?

    数据正不断影响关键业务的决策 这使得企业开始重新考虑 他们能从物联网中得到什么 如果你觉得物联网世界的不断增长只是一时的狂热 那你就错了 一份关于M2M技术的研究报告表明 到2020年 通过传感器控制 监控以及自动化管理的设备将达到125亿
  • 嵌入式 在开发板显示bmp图片、jpeg图片

    嵌入式 在开发板显示bmp图片 jpeg图片 一 简述 记 在GEC6818开发板 800W 480H 显示24位的bmp图片 使用开源的jpeg库显示jpeg图片 代码 链接 https pan baidu com s 1G3jzvdnc
  • 二叉树11:完全二叉树的节点个数

    主要是我自己刷题的一些记录过程 如果有错可以指出哦 大家一起进步 转载代码随想录 原文链接 代码随想录 leetcode链接 222 完全二叉树的节点个数 题目 给你一棵 完全二叉树 的根节点 root 求出该树的节点个数 完全二叉树 的定
  • QT:(4)解决在VS15下配置QT后没有QT GUI Application选项

    妈呀折腾了一上午终于出来了 其实就是按照其他博客的思路解决的 最主要就是注意一下细节 1 首先卸载之前安装的 注意自动更新扩展一定不要勾选上 2 进入下边网站下载 点击安装即可 本次下载的是2 4 3 https download qt i
  • 一个行程问题与对应的数列求和

    有一个看似简单的路程问题 却涉及到了微积分的收敛 题目如下 一段路程长度140Km 张三 李四两个人从两端骑自行车相向而行 大黄狗和张三在一起 张三速度15Km h 李四速度20Km h 大黄狗25Km h 大黄狗碰到李四 就折回跑向张三
  • office2013 excel 打开时提示excel词典xllex.dll文件丢失或损坏

    今天打开Excel时 发现报错 xllex dll文件丢失或损坏 我用的是office2013 网上找了好多都是2007的dll文件 导入不了 于是乎重装office 问题解决 但还是把xllex dll烤出来做个备份吧 参考下面步骤即可
  • Sublime Text Editor Recommended Settings

    http www cnblogs com dolphin0520 archive 2013 04 29 3046237 html 转载于 https www cnblogs com jast p 4737637 html
  • 8 月份 火火火火 的 GitHub 开源项目

    本期推荐开源项目目录 1 一个清新文艺的微社区 2 虚拟桌宠模拟器 3 Docusign开源替代方案 4 单词肌肉记忆锻炼软件 5 中文对话式大语言模型 01 一个清新文艺的微社区 一个美观清新的微社区开源项目 整套系统使用 Go Zinc
  • OpenCV实战(29)——视频对象追踪

    OpenCV实战 29 视频对象追踪 0 前言 1 追踪视频中的对象 2 中值流追踪器算法原理 3 完整代码 小结 系列链接 0 前言 我们已经学习了如何跟踪图像序列中点和像素的运动 但在多数应用中 通常要求追踪视频中的特定移动对象 首先确
  • Qt实现阴影边框,可拖动,可缩放窗口(二)

    通过paintEvent来实现的 绘制方形的阴影没问题 但是绘制圆角阴影的话 发现圆角不够圆润 而且有断裂的感觉 pragma once include
  • ChatGPT引爆变革:首个被颠覆的行业揭秘!

    随着人工智能的飞速发展 自然语言处理技术逐渐渗透到内容创作领域 作为一种先进的对话型AI系统 ChatGPT正改变着传统的写作方式 本文将探讨ChatGPT如何颠覆内容创作行业 以及其中的一些引人入胜的案例 ChatGPT是基于GPT架构的
  • 蓝牙App设计2:使用Android Studio制作一个蓝牙软件(包含:代码实现等)

    前言 蓝牙聊天App设计全部有三篇文章 一 UI界面设计 二 蓝牙搜索配对连接实现 三 蓝牙连接聊天 这篇文章是 二 蓝牙搜索配对连接实现 课程1 Android Studio小白安装教程 以及第一个Android项目案例 Hello Wo
  • 习题8-8 判断回文字符串 (20分)

    本题要求编写函数 判断给定的一串字符是否为 回文 所谓 回文 是指顺读和倒读都一样的字符串 如 XYZYX 和 xyzzyx 都是回文 函数接口定义 bool palindrome char s 函数palindrome判断输入字符串cha
  • 白月黑羽教python_白月黑羽Python在线教程

    推荐白月黑羽Python在线教程 白月黑羽 站在初学者的角度为大家安排了Python学习教程 帮助大家迅速掌握程序开发技能 http www python3 vip doc tutorial python home 变量 和 注释 本文目录
  • yaml 学习笔记

    yaml学习 配置 Yet Another Markup Language 发音 j m l 1 yaml文件规则 1 区分大小写 2 使用缩进表示层级关系 3 使用空格键缩进 而非Tab键缩进 4 缩进的空格数目不固定 只需要相同层级的元
  • Spring Cache @Cacheable @CachePut @CacheEvict 讲解和使用案例

    原文链接 https blog csdn net lpw cn article details 84642647 Spring的缓存管理可谓是相当的方便 与其他功能的风格一致 同样的在需要管理的地方添加一个注解 可以是方法 也可以是类 使用