缓存-Spring Cache 缓存抽象

news2024/12/25 2:34:33

缓存-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.coloradmin.cn/o/1181460.html

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

相关文章

图形推理 | 判断推理

文章目录 一、位置规律二、样式规律三、属性规律四、数量规律 一、位置规律 平移 方向&#xff1a;直线&#xff08;上下、左右、斜对角线&#xff09;、绕圈&#xff08;顺逆时针&#xff09;常见步数&#xff1a;恒定、递增&#xff08;等差&#xff09; 旋转 方向&#xff…

优化仓储分拣流程——WMS系统的分拣方法

在现代物流管理中&#xff0c;仓储分拣是一个至关重要的环节。为了提高分拣效率和准确性&#xff0c;越来越多的企业采用WMS系统来支持分拣操作&#xff0c;帮助企业优化仓储分拣流程。 1. 分拣策略制定&#xff1a; WMS系统可以根据不同的业务需求和产品特性&#xff0c;制定…

机器学习 - DBSCAN聚类算法:技术与实战全解析

目录 一、简介DBSCAN算法的定义和背景聚类的重要性和应用领域DBSCAN与其他聚类算法的比较 二、理论基础密度的概念核心点、边界点和噪声点DBSCAN算法流程邻域的查询聚类的形成过程 参数选择的影响 三、算法参数eps&#xff08;邻域半径&#xff09;举例说明&#xff1a;如何选择…

2021-2023神经辐射场(NeRF)118篇顶会论文合集(已分类整理)

有没有发现最近神经辐射场相关话题又有点爆了&#xff1f; 其实NeRF一直都挺火的&#xff0c;相关论文在Google Scholar上引用量已经超过6000次&#xff0c;每年顶级视觉会议如CVPR、ICCV、ECCV等都有大量关于神经辐射场的高质量工作被接受。许多科研机构和公司比如微软、Face…

使用RTSP接入安防监控EasyCVR平台,如何配置系统参数以减少起播时间?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台可拓展性强、…

软件外包团队的人员构成

软件外包团队的人员构成和职责可以因项目的性质和复杂度而有所不同&#xff0c;但通常包括以下一些核心角色和职责&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.项目经理&#xff08;Project Man…

Redis 的缓存击穿,穿透,雪崩及其解决方案

1 缓存穿透 什么是缓存穿透&#xff1f; 大量请求的 key 是不合理的&#xff0c;根本不存在于缓存中&#xff0c;也不存在于数据库中 。导致这些请求直接到了数据库上&#xff0c;根本没有经过缓存这一层&#xff0c;对数据库造成了巨大的压力&#xff0c;可能直接就被这么多…

现货黄金分析:多空高位博奕 黄金上行受阻

上周五&#xff0c;美国10月非农就业人数不及预期&#xff0c;失业率升至近两年新高&#xff0c;表明美国劳动力市场有所降温&#xff0c;数据公布后10年期美债收益率一度跌破4.50%&#xff0c;为9月26日以来最低水平&#xff0c;与此同时&#xff0c;现货金价跳升至2003.55美元…

【Unity】第二章 思考方式与构造 | 碰撞器/刚体/预设/组件

《Unity神技大人炼成记》第二章-思考方式与构造 Unity版本&#xff1a;2019.4.23f1c1 相关文章&#xff1a;第一章&#xff1a;开天辟地&#xff08;场景搭建-天空 山脉 草木 湖泊&#xff09; 粉色矩形是截图后添加&#xff0c;以便辨认操作位置有些步骤只是为了体现一些属性…

uniApp获取当前位置经纬度

以下是使用uni.getLocation获取当前位置的示例代码&#xff1a; 调用uni.getLocation方法获取当前位置信息 uni.getLocation({type: wgs84, // 坐标类型&#xff0c;默认为wgs84&#xff0c;可选的值为gcj02和bd09llsuccess: res > {// 获取成功&#xff0c;经度和纬度在r…

C语言编写学生成绩管理系统-要求有增删改查(C语言基础题-9道)

文章目录 1-5题题目例题8&#xff08;难度★ ★ ★ ★ ☆&#xff09;例题9&#xff08;难度★ ★ ☆ ☆ ☆&#xff09; 答案例题8答案1解析 答案2解析 例题9答案1解析 答案2解析 1-5题 C语言基础例题1-3题-指针篇 C语言基础例题4-5题-二维数组篇 C语言基础例题6-7题-结构体篇…

Go语言开发环境安装,hello world!

1. Go开发包SDK https://golang.google.cn/dl/&#xff08;国内也可以安装&#xff09; 根据自己电脑下载对应的安装包&#xff0c;我懒下载了msi安装 然后一路点确定安装Go 2.安装GoLand https://www.jetbrains.com/go/download/#sectionwindows 下载安装包 一路确定安装完…

成集云 | 英克对接零售O2O+线上商城 | 解决方案

方案介绍 零售O2O线上商城是一种新型的商业模式&#xff0c;它通过线上和线下的融合&#xff0c;提供更加便捷的购物体验。其中&#xff0c;O2O指的是线上与线下的结合&#xff0c;通过互联网平台与实体店面的结合&#xff0c;实现线上线下的互动和协同。线上商城则是指通过互…

04【保姆级】-GO语言指针

之前我学过C、Java、Python语言时总结的经验&#xff1a; 先建立整体框架&#xff0c;然后再去抠细节。先Know how&#xff0c;然后know why。先做出来&#xff0c;然后再去一点点研究&#xff0c;才会事半功倍。适当的囫囵吞枣。因为死抠某个知识点很浪费时间的。对于GO语言&a…

sed续与awk(粗糙版)

s:sed d 替换功能&#xff0c;改 s:替换字符串 格式是&#xff1a;sed -n s/需要替换的原内容/替换后的内容/(ps&#xff1a;数字是替换每行中的第几个&#xff0c;g代表是全内容替换)p 替换的文件地址 例如&#xff1a; c:整行替换 y:字符替换&#xff0c;替换前后的字符串…

富士康推进印度制造的计划倍速,中国制造iPhone占比下滑较快

日前知名苹果分析师郭明錤指出今年印度制造的iPhone占比达到12%&#xff0c;比预期的7%增加四成以上&#xff0c;比去年的占比更是增加2倍&#xff0c;这主要是因为富士康快速扩张了印度工厂的产能。 郭明錤指出印度制造的iPhone主要是由富士康贡献的&#xff0c;今年印度制造的…

信创背景下,IAM统一身份管理联合国产身份域管,助力央国企构建数字身份新底座

数字身份底座是企业数字化的基石。数字时代&#xff0c;IAM 统一身份管理系统结合微软 AD 是央国企、金融机构数字身份建设的通用架构。国产化改造浪潮中&#xff0c;国外身份管理系统&#xff08;如微软 AD&#xff09;无法适配国产化异构 IT 环境。从业务和安全角度考虑&…

【微服务 Spring Cloud 6】服务如何拆分?使用微服务的注意事项?

目录 一、前言二、单体服务的弊端三、微服务化四、服务如何拆分&#xff1f;1、拆分原则2、拆分时机和拆分方法3、拆分实践 五、使用微服务的注意事项1、确保相关业务和利益相关者的支持2、确定微服务的拆分粒度3、遵循微服务架构的原则4、确保接口的稳定性5、关注数据一致性6、…

ros1 自定义订阅者Subscriber的编程实现

话题模型 图中&#xff0c;我们使用ROS Master管理节点。 有两个主要节点&#xff1a; Publisher&#xff0c;名为Turtle Velocity&#xff08;即海龟的速度&#xff09;Subscriber&#xff0c;即海龟仿真器节点 /turtlesim Publisher(Turtle Velocity)&#xff0c;发布Messa…