缓存-Spring Cache 缓存抽象

缓存-Spring Cache 缓存抽象

       Spring从版本3.1开始提供非侵入的将Cache集成到Spring应用的方式。Spring Cache提供Cache的统一抽象,支持集成各种不同的缓存解决方案。从4.1版本开始,提供了注解和更多的定制参数。

       Spring Cache 抽象提供了对Java方法的缓存,使用Spring Cache缓存,当方法调用使用相同的参数,调用结果被缓存下来,当方法被再次调用时将直接返回参数结果。

关键类和接口

Cache

org.springframework.cache.Cache 提供Spring框架中使用的Cache的统一抽象功能, 具体的实现类使用实际的缓存解决方案。

  • NoOpCache: 空缓存,没有实际的缓存实现
  • EhCacheCache: 使用EhCache缓存方案。
  • CaffeineCache: 使用Java CaffeineCache。Caffeine提出了一种更高效的近似LFU准入策略的缓存结构TinyLFU及其变种W-TinyLFU,借鉴Guava Cache的设计经验,是一款功能强大,性能更优本地缓存。
  • JCacheCache: Javax Cache 标准接口,类似于Spring Cache的 JavaJ JSR缓存规范。
  • ConcurrentMapCache: 使用ConccrentMap的缓存实现。
  • TransactionAwareCacheDecorator: 识别Spring 事务的缓存实现装饰模式,只要当事务提交时才触发缓存的更新。

CacheManager

org.springframework.cache.CacheManager:Spring cache 管理API。不同的CacheManager实现提供对相应Cache实现缓存的管理,通过管理API Cache getCache(String name);方法对外提供。

CacheResolver

org.springframework.cache.interceptor.CacheResolver 方法调用拦截使用来获取Cache实现的Resolver,通常使用相应的CacheManager实现类来获取Cache。

KeyGenerator

org.springframework.cache.interceptor. KeyGenerator: 缓存中Key的生成实现。默认的key生成器:org.springframework.cache.interceptor.SimpleKeyGenerator 类

1.    方法没有参数则使用SimpleKey.EMPTY

2.    方法只有一个参数:key=唯一参数

3.    方法有多个参数:SimpleKey(params)

可以通过实现org.springframework.cache.interceptor.KeyGenerator接口定制key生成器。

使用Spring Cache

启用Spring Cache

@Configuration

@EnableCaching

注解使用

@Cacheable: 作用于方法之上,配置方法缓存

@Cacheable("cacheName"): 指定用于缓存结果的缓存名称,当指定多个名称时,方法调用将在多个缓存中查找相同参数的方法调用,命中即返回。

Cache 的key

       指定KeyGenerator:

@Cacheable(cacheNames="XXX", keyGenerator="myKeyGenerator")。

       通过SpEL指定key

       @Cacheable(cacheNames="books", key="#isbn")

public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@CachePut: @CachePut指定的方法不影响方法的执行,方法执行结果将用于更新缓存。@CachePut支持同@Cacheable一样的配置。

示例:

@CachePut(cacheNames="book", key="#isbn")

public Book updateBook(ISBN isbn, BookDescriptor descriptor)

@CacheEvict: 触发缓存清理陈旧或无用的数据。可以配置指定数据的清理或Cache范围的清理。

示例:

@CacheEvict(cacheNames="books", allEntries=true)

public void loadBooks(InputStream batch)

@Caching: 在一个方法上指定触发缓存的多个操作。

示例:

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })

public Book importBooks(String deposit, Date date)

@CacheConfig: 以上的注解都是方法级别的注解,@CacheConfig提供类级别的公共配置,该类下的方法级别配置如无指定则使用类级别上的@CacheConfig。

实现方式

Spring AOP

使用 Spring AOP切面实现Cache相关方法的拦截获取缓存和Cache请求的处理

  1. 配置切面: 所有所有类和所有方法都进行拦截

org.springframework.cache.interceptor.CacheProxyFactoryBean

相关代码:

private Pointcut pointcut = Pointcut.TRUE;

        

protected Object createMainInterceptor() {

         this.cacheInterceptor.afterPropertiesSet();

         return new DefaultPointcutAdvisor(this.pointcut, this.cacheInterceptor);

}

  1. org.springframework.cache.interceptor.CacheInterceptor 实现

org.springframework.cache.interceptor.MethodInterceptor接口,

CacheAspectSupport.execute方法是Spring Cache核心处理流程,下面是主要流程的部分代码解析:

// 处理CacheEvict请求

processCacheEvicts(contexts.get(CacheEvictOperation.class), true,

         CacheOperationExpressionEvaluator.NO_RESULT);

// 从缓存中查询是否存在缓存

Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));

// 如未命中,生成CachePut请求:缓存条件满足

List<CachePutRequest> cachePutRequests = new ArrayList<>();

if (cacheHit == null) {

         collectPutRequests(contexts.get(CacheableOperation.class),

                          CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);

}

Object cacheValue;

Object returnValue;

if (cacheHit != null && !hasCachePut(contexts)) {

         //缓存命中,并且没有Put需求,返回缓存值

         cacheValue = cacheHit.get();

         returnValue = wrapCacheValue(method, cacheValue);

}

else {

         //未命中,调用对象,获取可缓存值

         returnValue = invokeOperation(invoker);

         cacheValue = unwrapReturnValue(returnValue);

}

//检查是否存在CachePut请求

collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);

// 缓存更新

for (CachePutRequest cachePutRequest : cachePutRequests) {

         cachePutRequest.apply(cacheValue);

}

// 处理缓存Evicts请求

rocessCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);      

return returnValue;

}

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

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

相关文章

Fiddler工具使用

Fiddler 功能强大的免费HTTP调试代理工具&#xff0c;位于客户端和服务器端之间的代理&#xff0c;可以针对特定的请求&#xff0c;分析请求数据、设置断点、调试web应用、修改请求的数据&#xff0c;甚至可以修改服务器返回的数据&#xff0c;功能非常强大。 菜单栏 1、Fil…

yo!这里是STL::unordered系列简单模拟实现

目录 前言 相关概念介绍 哈希概念 哈希冲突与哈希函数 闭散列 框架 核心函数 开散列 框架 核心函数 哈希表&#xff08;开散列&#xff09;的修改 迭代器实现 细节修改 unordered系列封装 后记 前言 我们之前了解过map和set知道&#xff0c;map、set的底层结构是…

电脑软件:推荐一款电脑多屏幕管理工具DisplayFusion

下载https://download.csdn.net/download/mo3408/88514558 一、软件简介 DisplayFusion是一款多屏幕管理工具&#xff0c;它可以让用户更轻松地管理连接到同一台计算机上的多个显示器。 二、软件功能 2.1 多个任务栏 通过在每个显示器上显示任务栏&#xff0c;让您的窗口管理更…

MATLAB绘图中文显示为方框

MATLAB绘图中文显示为方框 MATLAB显示英文和字母没有问题&#xff0c;但是当显示中文时会显示乱码&#xff0c;中文显示为方框&#xff0c;如下图&#xff1a; 可以在绘图命令中添加如下代码&#xff1a; set(gca,Fontname,Monospaced); 例如&#xff1a; % 滤波器系数%低通…

16 DNS协议详解

1、DNS的由来 很难记住网站的 IP 地址&#xff0c;因而也需要一个地 址簿&#xff0c;就是DNS 服务器。DNS 在日常生活中非常重要。每个人上网&#xff0c;都需要访问它&#xff0c;因此一旦DNS出现故障&#xff0c;是非常可怕的。因而&#xff0c;DNS 服务器&#xff0c;一定…

装修服务预约小程序的内容如何

大小装修不断&#xff0c;市场中大小品牌也比较多&#xff0c;对需求客户来说&#xff0c;可以线下咨询也可以线上寻找品牌&#xff0c;总是可以找到满意的服务公司&#xff0c;而对装修公司来说如今线下流量匮乏&#xff0c;很多东西也难以通过线下方式承载&#xff0c;更需要…

【Java 进阶篇】Java Filter 快速入门

欢迎来到这篇有关 Java Filter 的快速入门指南&#xff01;如果你是一名 Java 开发者或者正在学习 Java Web 开发&#xff0c;Filter 是一个强大的工具&#xff0c;可以帮助你管理和控制 Web 应用程序中的请求和响应。本文将向你解释 Filter 的基本概念&#xff0c;如何创建和配…

84 柱状图中的最大的矩形(单调栈)

题目 柱状图中的最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 …

nginx图片资源管理转发

目标: 服务器上面 /home/images 里面作为文件资源管理器 代码: server {listen 80;server_name hello.world.cn;#apple-app和接口的关联文件location ~.*(images/miniapp)*\.(gif|jpg|jpeg|png)$ {root /home/;try_files $uri $uri/ 404;add_header Cache-Control &q…

spark读取和保存本机文件

保存spark sql到本地 要将Spark SQL中的数据导出到本地&#xff0c;可以使用DataFrame的write方码示例&#xff1a; 1. 导出为CSV文件&#xff1a; df.write.format("csv").option("header",/to/output.csv") – 的格式为CSV。 – option(“heade…

NLTK下载punkt

from nltk import word_tokenizesents [sent1, sent2] print(word_tokenize(sent1))报错&#xff1a; D:\Anaconda3\python.exe "D:/002 知识总结/007 NLP/NLP入门文章/词袋模型与句子相似度.py" [nltk_data] Error loading punkt: <urlopen error [SSL: [nltk_…

(六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题

前言 本节内容是关于使用分布式锁解决并发访问“超卖”问题的最终篇&#xff0c;在前面的章节中我们介绍了使用mysql的行锁、乐观锁、悲观锁解决并发访问导致的超卖问题&#xff0c;存在的问题是行锁、乐观锁、悲观锁不太灵活&#xff0c;需要和具体的业务耦合到一起&#xff…

面试官【说一下移动端1px的解决方案】

文章目录 前言使用伪类和transform使用border-image使用box-shadow使用媒体查询及scale使用viewport单位使用图片或SVG后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多…

再获5G RedCap能力认证!宏电5G RedCap工业智能网关通过中国联通5G物联网OPENLAB开放实验室测试验证

​近日&#xff0c;中国联通5G物联网OPENLAB开放实验室携手宏电股份完成5G RedCap工业智能网关端到端的测试验证&#xff0c;并颁发OPENLAB实验室面向RedCap终端的认证证书&#xff0c;为RedCap产业规模推广、全行业赋能打下坚实基础。 中国联通5G物联网OPENLAB开放实验室是中国…

为什么是LangChain?

文章目录 一、前言二、认识langchain1. langchain的主要组成2. 总览LangChain2. LangChain的六大核心模块1. Models&#xff1a;模型统一接口2. Prompts&#xff1a;管理 LLM 输入3. Chains&#xff1a;将 LLM 与其他组件相结合&#xff0c;执行多个chain4. Indexes&#xff1a…

使用LogBack替换Log4j

目录 1.删除log4j有关的依赖&#xff0c;添加logBack依赖 2.删除log4j配置文件&#xff0c;增加logback.xml配置文件 3.更改application.yml配置文件&#xff0c;log文件指向logback.xml 4.重启 1.删除log4j有关的依赖&#xff0c;添加logBack依赖 <dependency><gr…

掌动智能:云可观测性的主要特点及应用场景

云全景可观测性安全平台是一个跨架构、跨平台的可观测性方案&#xff0c;实现对云环境下的细粒度数据可视化&#xff0c;满足安全部门对云内部安全领域的多场景诉求&#xff0c;包括敏感数据动态监管、云网攻击回溯分析、攻击横移风险监控、云异常流量分析。本文将介绍掌动智能…

关于使用es数组的改变方式

一&#xff09;改变原数组的方法&#xff08;9个&#xff09; ES5&#xff1a; 1. pop() 删除一个数组中的最后的一个元素&#xff0c;并且返回这个元素。 2.shift() 删除数组的第一个元素&#xff0c;并返回这个元素。 3.push() 可向数组的末尾添加一个或多个元素&#xf…

【Nginx39】Nginx学习:upstream服务器组模块

Nginx学习&#xff1a;upstream服务器组模块 最后一个重点模块内容啦&#xff0c;感谢坚持到现在的你和我。总算是向大佬的道路上又前进了一步了。今天的内容主要是服务器组的配置&#xff0c;其实更直白点&#xff0c;就是 Nginx 负载均衡的配置模块。会不会有小伙伴不明白负载…

kubernetes集群编排(8)

k8s资源监控 资源限制 上传镜像 [rootk8s2 limit]# vim limit.yaml apiVersion: v1 kind: Pod metadata:name: memory-demo spec:containers:- name: memory-demoimage: stressargs:- --vm- "1"- --vm-bytes- 200Mresources:requests:memory: 50Milimits:memory: 100…