SpringCache源码解析(一)-Annotation

news/2024/9/18 14:44:57/ 标签: spring, java, spring boot

〇、常用注解

包地址注解名作用域作用
org.springframework.cache.annotationCacheConfig类级别s设置缓存的公共配置
Cacheable方法级别缓存读取操作
CacheEvict方法级别缓存失效操作
CachePut方法级别缓存更新操作
Caching方法级别h混合读取、失效、更新操作
CacheConfig方法级别统一配置缓存注解的属性,作用于类
EnableCaching方法级别开启缓存功能

一、@Cacheable注解

属性默认值描述
value缓存的名称,在 spring 配置文件中定义,必须指定至少一个
cacheNames缓存的名称,在 spring 配置文件中定义,必须指定至少一个
key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
keyGenerator
cacheManager
cacheResolver
condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存。不能使用返回结果
unless不缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 false才进行缓存。可以使用返回结果
sync
  • 简介:表示该方法执行后的结果可以被缓存;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;
  • 执行逻辑:查找对应的缓存是否存在,若不存在,该方法会被调用,并且将返回结果放入缓存;若存在,则不调用方法,直接返回缓存的结果;

1.1 案例

注解业务案例 单一缓存名称和键:

java">@Cacheable("books")
public Book findBookById(String id) {// 业务逻辑
}

多个缓存名称和条件:

java">@Cacheable(value = {"books", "archivedBooks"}, condition = "#id.length() > 10")
public Book findBookWithComplexKey(String id) {// 业务逻辑
}@Service
public class MyService {/*** 一个使用 @Cacheable 所有属性的案例。* * @param id 用户ID* @return 返回用户对象*/@Cacheable(value = "users",          // 缓存名称key = "#id",              // 缓存键,使用SpEL表达式condition = "#id.length() > 3",  // 缓存条件,只有当ID长度大于3时才缓存unless = "#result == null" // 除非条件,如果结果为null,则不缓存)public User findUserById(String id) {// 模拟数据库查询操作,这里假设ID长度小于3时没有结果if (id == null || id.length() <= 3) {return null;}return performDatabaseQuery(id);}private User performDatabaseQuery(String id) {// 模拟数据库查询逻辑return new User(id, "Name based on ID");}
}

1.2 核心源码

java">@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {// 缓存KEY所在缓存的标识符,支持多个,CSV格式@AliasFor("cacheNames")String[] value() default {};// 缓存KEY所在缓存的标识符,支持多个,CSV格式@AliasFor("value")String[] cacheNames() default {};// 缓存的KEY,支持SpEL表达式动态计算// 默认为空(缺省按照方法的所有参数组合生成SimpleKey)String key() default "";// 缓存KEY生成器String keyGenerator() default "";// 缓存管理器String cacheManager() default "";// 缓存解析器String cacheResolver() default "";// 缓存的条件,使用SpEL表达式,方法调用前计算,当结果为true时执行动作// 默认为空,表示总是缓存方法返回值String condition() default "";// 否决缓存的条件,使用SpEL表达式,方法调用后计算(可使用result),当结果为true时不执行动作// 默认为空,表示永不否决;String unless() default "";// 使用异步模式标识boolean sync() default false;
}

二、@CachePut

注解作用:@CachePut 注解用于在方法执行后更新缓存。
注解属性:与@Cacheable相同。

  • 简介:表示该方法执行后的结果需要更新到缓存;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;
  • 执行逻辑:和Cacheable不同的是,带有CachePut注解的方法一定会被执行,方法执行后的结果由condition/unless判定是否存入缓存;

2.1 案例

java">@CachePut("books")
public Book updateBookDetails(String id, Book details) {// 业务逻辑
}@Service
public class MyService {/*** 使用 @CachePut 所有属性的案例。** @param user 用户对象,包含ID* @return 更新后的用户对象*/@CachePut(value = "users",      // 缓存名称key = "#user.id",     // 缓存键,使用SpEL表达式condition = "#user.age > 18"  // 条件,只有当用户年龄大于18时才更新缓存)public User updateUserProfile(User user) {// 模拟更新用户信息的业务逻辑return performUpdate(user);}private User performUpdate(User user) {// 模拟更新逻辑user.setName("Updated Name");return user;}
}

2.2 核心源码

java">@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {// 缓存KEY所在缓存的标识符,支持多个,CSV格式@AliasFor("cacheNames")String[] value() default {};// 缓存KEY所在缓存的标识符,支持多个,CSV格式@AliasFor("value")String[] cacheNames() default {};// 缓存的KEY,可以为空(缺省按照方法的所有参数组合生成SimpleKey);// 支持SpEL表达式String key() default "";// KEY的生成器String keyGenerator() default "";// 缓存管理器String cacheManager() default "";// 缓存解析器String cacheResolver() default "";// 放置缓存的条件,使用SpEL表达式,方法调用后计算(可使用result),当结果为true时执行动作// 默认为空,表示方法结果总是被缓存String condition() default "";// 否决放置缓存的条件,使用SpEL表达式,方法调用后计算(可使用result),当结果为true时不执行动作// 默认为空,表示永不否决;String unless() default "";
}

三、@CacheEvict

注解作用:@CacheEvict 注解用于在方法执行后清除缓存。

注解属性介绍

  • value 或 cacheNames: 指定缓存名称,可以是单个或多个;

  • allEntries: 清除所有缓存项;

  • condition: 指定清除缓存的条件SpEL表达式;

  • 简介:表示清除该方法的缓存KEY对应的缓存;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;

3.1 案例

清除特定缓存名称的条目:

java">@CacheEvict("books")
public void deleteBook(String id) {// 业务逻辑
}

清除所有缓存名称的所有条目:

java">@CacheEvict(allEntries = true)
public void clearAllCaches() {// 业务逻辑
}

3.2 核心源码

java">@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {// 缓存KEY所在缓存的标识符,支持多个,CSV格式@AliasFor("cacheNames")String[] value() default {};// 缓存KEY所在缓存的标识符,支持多个,CSV格式@AliasFor("value")String[] cacheNames() default {};// 缓存的KEY,可以为空(缺省按照方法的所有参数组合生成SimpleKey);// 支持SpEL表达式String key() default "";// KEY的生成器String keyGenerator() default "";// 缓存管理器String cacheManager() default "";// 缓存解析器String cacheResolver() default "";// 清除缓存的条件,使用SpEL表达式,执行次序由beforeInvocation()决定// 默认为空,表示总是清除缓存String condition() default "";// 删除缓存中所有条目标识// 默认为false,表示只删除指定KEY的值boolean allEntries() default false;// 方法调用前执行标识// 默认为false,表示方法成功调用(未抛出异常)后执行;为true则方法调用前执行boolean beforeInvocation() default false;
}

四、@Caching(不常用)

注解作用:@Caching 注解用于组合多个缓存操作。

注解属性介绍

  • value: 包含多个缓存操作的数组;

  • 简介:表示多个Cache注解的组注解;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;

4.1 案例

java">@Caching(cacheable = {@Cacheable("books")},put = {@CachePut("books")},evict = {@CacheEvict("archivedBooks")}
)
public Book processBook(String id, Book details) {// 业务逻辑
}

4.2 核心源码

java">@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {// Cacheable集合Cacheable[] cacheable() default {};// CachePut集合CachePut[] put() default {};// CacheEvict集合CacheEvict[] evict() default {};
}

五、@CacheConfig

注解作用:@CacheConfig 注解用于在类级别提供缓存相关的共享配置。

注解属性介绍

  • cacheNames: 指定类中所有缓存操作的默认缓存名称;

  • keyGenerator: 指定默认的缓存键生成器;

  • condition: 指定类中所有缓存操作的默认条件;

  • 简介:提供在类层次上共享缓存相关配置的机制;只可作用于类上;
    当作用在某个类上,会给这个类中定义的所有缓存动作提供默认配置,当然,具体缓存动作的配置可覆盖提供的默认配置;

5.1 案例

java">@CacheConfig(cacheNames = "books", keyGenerator = "customKeyGenerator")
public class BookService {// 类中的方法可以使用缓存注解
}

5.2 核心源码

java">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheConfig {// 缓存KEY所在缓存的标识符,支持多个,CSV格式String[] cacheNames() default {};// KEY的生成器String keyGenerator() default "";// 缓存管理器String cacheManager() default "";// 缓存解析器String cacheResolver() default "";
}

六、@EnableCaching

简介:
表示启用Spring的注解驱动的缓存管理能力,和@Configuration配合使用;

必须创建CacheManager Bean,Spring框架不会提供默认值;@EnableCaching会根据类型搜索CacheManager Bean,因此CacheManager Bean的命名并不重要;
可以实现CachingConfigurer接口的cacheManager()方法来创建@EnableCaching指定的CacheManager Bean,这种情况下需要明确提供KeyGenerator(@EnableCaching会默认提供SimpleKeyGenerator);如果不需要自定义,可以考虑从CachingConfigurerSupport扩展,它为所有方法提供了默认实现;

6.1 核心源码

java">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {// 代理模式:CGLIB or JDK Interface// 默认为false,表示基于JDK Interface// 设置为true,会影响所有需要代理的Spring管理的Beanboolean proxyTargetClass() default false;// 缓存应用模式:Proxy or AspectJ// Proxy模式只允许通过代理拦截调用,不会拦截同一类中的本地调用// AspectJ模式下,proxyTargetClass()无效,会拦截同一类中的本地调用AdviceMode mode() default AdviceMode.PROXY;// 特定连接点应用多个建议时,缓存操作的执行顺序int order() default Ordered.LOWEST_PRECEDENCE;
}

http://www.ppmy.cn/news/1516975.html

相关文章

springboot-从0开始创建一个starter

创建一个Spring Boot Starter是一个很好的方式来封装常用的配置和依赖&#xff0c;以便在多个项目中重用。以下是一个简单的指南&#xff0c;教你如何开发一个自己的Spring Boot Starter。 一、创建步骤 1. 创建项目 首先&#xff0c;你需要创建一个Maven或Gradle项目。这里我…

QMT量化+通道快速,完美结合应对市场!

关注韭菜修养&#xff08;同名全拼音&#xff09;&#xff0c;投资道路我们一起成长&#xff01;第一&#xff1a;国内的量化交易软件众多&#xff0c;我们可以参考这几个维度①全内存极速交易&#xff1a;全内存交易&#xff0c;单笔延时&#xff1c;1ms满足量化高频交易客户对…

谷粒商城实战笔记-249-商城业务-消息队列-RabbitMQ工作流程

文章目录 一&#xff0c;基本概念二&#xff0c;消息从producer到consumer的过程 一&#xff0c;基本概念 RabbitMQ是一个流行的开源消息代理软件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP&#xff09;。以下是RabbitMQ的一些基本概念&#xff1a; Broker&#x…

3 pytest Fixture

目录 3.1 通过 conftest.py 共享 fixture3.2 使用 fixture 执行配置及销毁逻辑3.3 使用 --setup-show 回溯 fixture 的执行过程3.4 使用 fixture 传递测试数据3.5 使用多个 fixture3.6 指定 fixture 作用范围3.7 使用 usefixtures 指定 fixture3.8 为常用 fixture 添加 autouse…

windows C++- WRL 使用计时器

由于WRL技术已经不作为主流继续发展&#xff0c;所以这里这个文档主要是收录WRL作为一些特殊情况下的查阅和理解windows体系开发的技术脉络&#xff0c;故本文档仅仅演示各项关键技术&#xff0c;例如本文档如何使用 Windows 运行时 C 模板库 (WRL) 启动异步操作并在操作完成时…

.ipynb文件:交互式 Jupyter Notebook

Python 接口文件&#xff08;带有扩展名的文件.pyi&#xff09;&#xff0c;或称为 Python 存根文件&#xff0c;在使用类型提示增强 Python 代码方面发挥着至关重要的作用。 当你遇到名称以 .ipynb、.pyi、.pyc 等结尾的 Python 文件时&#xff0c;你是否会感到困惑&#xff…

asp.net core在win上的发布和部署

一、asp.net core两种发布方式 1、两个发布方式——【框架依赖发布】和【独立发布】 2、两种发布方式的差别 二、发布的详细过程 1、【生成】->【发布】 2、框架依赖发布 设置发布参数&#xff0c;然后进行发布 发布好的文件&#xff0c;把它们放到一个新的目录文件夹里 …

LLaMA Factory微调Llama3模型

LLaMA Factory是一款开源低代码大模型微调框架&#xff0c;集成了业界最广泛使用的微调技术&#xff0c;支持通过Web UI界面零代码微调大模型&#xff0c;目前已经成为开源社区内最受欢迎的微调框架。 &#x1f4a5;GPU推荐使用24GB显存的A10&#xff08;ecs.gn7i-c8g1.2xlarg…

百度:未来or现在 顾此失彼?

用AI押注未来&#xff0c;却丢了现在 国内AI先行者百度 走到哪了&#xff1f; 作为这个星球最热门的概念&#xff0c;AI无疑是个好故事&#xff0c;不只是百度&#xff0c;美股的一众科技公司几乎都在讲述自己的AI投入及发展成果&#xff0c;市值也随着AI预期坐过山车。而市场…

css基础学习总结(一)

文章目录 一. 选择器1. 标签选择器2. 类选择器3. ID选择器4. 分组选择器5. 派生与子元素选择器6. 属性选择器7. 伪类选择器8. 伪对象选择器9. 选择器的优先级别css优先级 的 6大分类 一. 选择器 1. 标签选择器 选择器例子描述elementp/div/span选择所有含有指定标签的元素 &…

神经网络参数个数的计算

计算神经网络中参数的个数取决于网络的结构&#xff0c;包括层的类型和每层的节点数。以下是一些常见层类型的参数计算方法&#xff1a; 全连接层&#xff08;Fully Connected Layer&#xff09;&#xff1a; 参数个数 输入节点数 输出节点数 输出节点数&#xff08;偏置项…

什么是数据库 DevOps?

原文地址 https://www.bytebase.com/blog/what-is-database-devops/ 在深入研究数据库 DevOps 之前&#xff0c;先回顾一下什么是 DevOps。它没有统一的定义&#xff0c;但我们知道它起源于软件开发方法与部署和运维的结合。 大约 2007 年和 2008 年&#xff0c;软件开发和 I…

中国高校发表科技论文及著作数量数据集(2009-2022年)

中国各地区的高校科技产出数据&#xff0c;包括27个指标&#xff0c;科技论文发表、著作出版、专利申请、专利转让、国家标准项等。这些指标综合反映了各地区高校在科学研究和技术开发方面的活跃程度及创新能力 一、数据介绍 数据名称&#xff1a;中国地区高校发表科技论文、…

TCP/IP 协议:互联网的基石

TCP/IP 协议:互联网的基石 引言 TCP/IP协议,全称为传输控制协议/互联网协议(Transmission Control Protocol/Internet Protocol),是现代互联网通信的基础。自20世纪70年代末期以来,TCP/IP协议已经成为全球互联网通信的通用语言,它定义了数据如何在网络上进行传输和路由…

【代码随想录训练营第42期 Day38打卡 - 动态规划Part6 - LeetCode 322. 零钱兑换 279.完全平方数 139.单词拆分

目录 一、做题心得 二、题目与题解 题目一&#xff1a;322. 零钱兑换 题目链接 题解&#xff1a;动态规划--完全背包 题目二&#xff1a; 279.完全平方数 题目链接 题解&#xff1a;动态规划--完全背包 题目三&#xff1a;139.单词拆分 题目链接 题解&#xff1a;动…

云轴科技ZStack AIOS平台智塔亮相FDS金融领袖峰会

人工智能&#xff08;AI&#xff09;正以前所未有的速度渗透到金融系统&#xff0c;推动着金融服务的创新和变革。这种深度融合不仅可以提高金融服务的效率和准确性&#xff0c;未来还可催生全新的金融产品和服务模式。尤其是生成式人工智能&#xff08;GenAI&#xff09;的出现…

系统分析师5-数据库特训专题

文章目录 1 数据库设计概述2 规范化与反规范化2.1 规范化2.2 反规范化2.3 案例分析例题1 3 数据库索引与视图的应用3.1 数据库索引3.2 数据库视图3.3 案例分析例题2 4 分布式数据库系统5 数据库分区分表分库5.1 案例分析例题3 6 分布式事务增补6.1 案例分析例题4 7 NoSQL8 附录…

redis实战——go-redis的使用与redis基础数据类型的使用场景(二)

一.go-redis操作hash 常用命令&#xff1a; redisClient.HSet("map", "name", "jack") // 批量设置 redisClient.HMSet("map", map[string]interface{}{"a": "b", "c": "d", "e"…

如何使用ssm实现基于SSM的旅游管理系统

TOC ssm285基于SSM的旅游管理系统jsp 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各行业&…

三级_网络技术_50_综合题(报文)

一、 下图是校园网某台主机在命令行模式执行某个命令时用wireshark捕获的数据包 请根据图中信息回答下列问题。 (1)该主机上执行的命令是__________ (2)该主机上使用的DNS服务器的IP地址是__________ (3)该主机的IP地址是__________ 该主机的MAC地址是__________ (4)主机…