本地缓存~

前言

Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中取而代之,基于LRU算法实现,支持多种缓存过期策略。

以下摘抄于https://github.com/ben-manes/caffeine/wiki/Benchmarks-zh-CN

基准测试通过使用Java microbenchmark harness 来提供准确的分析结果。这些缓存将被如下配置,

  • Caffeine 和 ConcurrentLinkedHashMap根据CPU的数量调整其内部大小。
  • Guava 并发度被配置为 64 (默认情况下为 4 来减少内存开销)。请注意Guava将会#2063 解决性能问题,但已经被积压多年(提升25倍以上!)。
  • Ehcache v2 内部被硬编码为100段, 而 v3 版本没有进行分段
  • Infinispan “old” 是一个类似Guava的缓存,并且并发度被配置为64
  • Infinispan "new"是使用无锁deque(默认版本为 v7.2+)重写的

本地缓存对比

特性GuavaCaffeine
自动加载实体到缓存中✔️✔️
自动刷新✔️✔️
过期或被删除的机制✔️✔️
自动回收✔️✔️
统计累计访问缓存✔️✔️
异步✔️
写入外界资源✔️
算法S-LRU 分段的最近最少未使用算法W-TinyLFU 高命中率、低内存占用
持久化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用指南

pom引入

<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId>
</dependency>

配置

  • maximumSize:

  • refreshAfterWrite

  • expireAfterWrite

  • expireAfterAccess

  • maximumWeight

preview

方法

  • Get

    如果Guava 的load()返回时null,那么get()会抛出异常ExecutionException,而Caffeine就不会,会返回null

  • getAll

    获取多个key的value,返回一个map

  • load

    刷新

  • getUnchecked(): guava才有,Caffeine没有,所以Caffeine需要做好控判断

  • Caffeine.newBuilder().build()创建LoadingCache

  • invalidate

  • cleanUp

缓存填充方法

  • 手动填充

    # 0. 构建LoadingCache
    Cache<String, DataObject> cache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).maximumSize(280).build();String key = "test";
    # 1. 缓存中不存指定的值,则方法将返回 null
    DataObject dataObject = cache.getIfPresent(key); cache.put(key, "20220510 Demo演示");
    # 2. return "20220510 Demo演示"
    dataObject = cache.getIfPresent(key);# 3. 如果key的值不存在,则返回“空时mock一个值”
    dataObject = cache.get(key, k -> "空时mock一个值"); # 4. 手动失效
    cache.invalidate(key);
    # 返回null
    dataObject = cache.getIfPresent(key);
    
  • 同步加载

    LoadingCache<String, DataObject> cache = Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.MINUTES).build(k -> "Data for " + k);
    
  • 异步加载

    AsyncLoadingCache<String, DataObject> cache = Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.MINUTES).buildAsync(k -> "Data for " + k);String key = "test-async";cache.get(key).thenAccept(dataObject -> {assertNotNull(dataObject);assertEquals("Data for " + key, dataObject.getData());
    });cache.getAll(Arrays.asList("test-async", "test-async2", "test-async3")).thenAccept(dataObjectMap -> assertEquals(3, 3));
    

注解的实现方式

Springboot 配置

spring:
# 配置缓存,初始缓存容量为10,最大容量为200,过期时间(这里配置写入后过期时间为3秒)cache:type: caffeinecaffeine:spec: initialCapacity=10,maximumSize=200,expireAfterWrite=3s

@Cacheable

 // key 是指传入时的参数@Cacheable(value="users", key="#id")public Integer find(Integer id) {return id;}
// 表示第一个参数
@Cacheable(value="users", key="#p0")public Long find(Long id) {return id;}
// 表示User中的id值@Cacheable(value="users", key="#user.id")public User find(User user) {return user;}// 表示第一个参数里的id属性值@Cacheable(value="users", key="#p0.id")public User find(User user) {return user;}// 表示第一个参数里的id属性值@Cacheable(value="users", key="#root.getXXX(#user.id)")public User find(User user) {return user;}public String getXXX(String id){// 获取上文问的traceid 方法// ...return 上下文的traceId;
}// 根据条件判断是否缓存@Cacheable(value="users", key="#user.id", condition="#user.id%2==0"/*,unless="#result==null"*/)public User find(User user) {return user;}

注意事项

  • SpringBoot启动类开启@EnableCaching

  • A class 调用 B class 的@Cacheable的方法,一定是public方法

  • A class 调用 B class 的@Cacheable的方法,B 一定是@Component、@Service等

  • B class 的@Cacheable的方法xx1调用@Cacheable的方法xx2,B缓存不起作用。解决方案:Spring上下文手动获取Bean实例调用xx2,或者AopContext.currentProxy())调用xx2,不过ApoContenxt这个,需要在启动累开启@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)

  • 开启@EnableCache,注意区分Redis的CacheManager,在注解通过指定@Cacheable(cacheManager=“caffeineCacheManager”,…)

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

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

相关文章

Unity Shader Graph 2D - 角色身体电流覆盖效果

在游戏中,通常会有游戏角色受到“电击”的效果,此时游戏角色身体上会覆盖有电流,该效果能表明游戏角色的当前状态,让玩家能够获得更直观更好的体验。 那么如何实现呢 首先创建一个ShaderGraph文件,命名为Current,再创建对应的材质球M_Current。 基础的资源显示 老规矩,…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.9 广播陷阱:形状不匹配的深层隐患

2.9 广播陷阱&#xff1a;形状不匹配的深层隐患 目录 #mermaid-svg-F0AgBChfSCGzOqa7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-F0AgBChfSCGzOqa7 .error-icon{fill:#552222;}#mermaid-svg-F0AgBChfSCGzOqa7 …

解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩

解锁豆瓣高清海报(二): 使用 OpenCV 拼接和压缩 脚本地址: 项目地址: Gazer PixelWeaver.py pixel_squeezer_cv2.py 前瞻 继上一篇“解锁豆瓣高清海报(一) 深度爬虫与requests进阶之路”成功爬取豆瓣电影海报之后&#xff0c;本文将介绍如何使用 OpenCV 对这些海报进行智…

vue入门到实战 二

目录 2.1 计算属性computed 2.1.1什么是计算属性 2.1.2 只有getter方法的计算属性 2.1.3 定义有getter和setter方法的计算属性 2.1.4 计算属性和methods的对比 2.2 监听器属性watch 2.2.1 watch属性的用法 2.2.2 computed属性和watch属性的对比 2.1 计算属性computed…

【DeepSeek】本地快速搭建DeepSeek

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 博客内容主要围绕&#xff1a; 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 本地快速搭建DeepSeek一、安装及配置ollama二、DeepSeek模型…

Spring WebFlux揭秘:下一代响应式编程框架,与Spring MVC有何不同?

Spring WebFlux和Spring MVC都是Spring家族里的成员&#xff0c;它们都能帮助我们开发Web应用&#xff0c;但工作方式有所不同。 可以把Spring MVC想象成一个服务员&#xff0c;每次有客人&#xff08;请求&#xff09;来&#xff0c;它就会专门找一个服务员&#xff08;线程&a…

基于微信小程序的实习记录系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

MySQL5.5升级到MySQL5.7

【卸载原来的MySQL】 cmd打开命令提示符窗口&#xff08;管理员身份&#xff09;net stop mysql&#xff08;先停止MySQL服务&#xff09; 3.卸载 切换到原来5.5版本的bin目录&#xff0c;输入mysqld remove卸载服务 测试mysql -V查看Mysql版本还是5.5 查看了环境变量里的…

TensorFlow 简单的二分类神经网络的训练和应用流程

展示了一个简单的二分类神经网络的训练和应用流程。主要步骤包括&#xff1a; 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与部署 加载和应用已训练的模型 1. 数据准备与预处理 在本例中&#xff0c;数据准备是通过两个 Numpy 数…

使用朴素贝叶斯对散点数据进行分类

本文将通过一个具体的例子&#xff0c;展示如何使用 Python 和 scikit-learn 库中的 GaussianNB 模型&#xff0c;对二维散点数据进行分类&#xff0c;并可视化分类结果。 1. 数据准备 假设我们有两个类别的二维散点数据&#xff0c;每个类别包含若干个点。我们将这些点分别存…

AI视频编码器(3.2) 《Swin Transformer V2: Scaling Up Capacity and Resolution》

arxiv链接自监督训练用到了SimMIM 论文链接。我觉得,SimMIM与MAE的区别在于,前者只是一个1-layer的prediction head,而后者是多层transformer结构的decoder。可参考Swin Transformer V2(CVPR 2022)论文与代码解读。总结 图中展示了三个创新,从左到右有三处红色结构,分别…

前端进阶:深度剖析预解析机制

一、预解析是什么&#xff1f; 在前端开发中&#xff0c;我们常常会遇到一些看似不符合常规逻辑的代码执行现象&#xff0c;比如为什么在变量声明之前访问它&#xff0c;得到的结果是undefined&#xff0c;而不是报错&#xff1f;为什么函数在声明之前就可以被调用&#xff1f…

Baklib赋能企业提升内容中台构建效率的全新路径解析

内容概要 在当今数字化转型的大潮中&#xff0c;企业面临着前所未有的挑战与机遇。为了顺应市场的发展趋势&#xff0c;提高运营能力&#xff0c;搭建高效的内容中台已成为企业迫在眉睫的任务。内容中台不仅仅是一个技术架构的集合&#xff0c;它更是企业实现数据共享、资源整…

计算机网络——流量控制

流量控制的基本方法是确保发送方不会以超过接收方处理能力的速度发送数据包。 通常的做法是接收方会向发送方提供某种反馈&#xff0c;如&#xff1a; &#xff08;1&#xff09;停止&等待 在任何时候只有一个数据包在传输&#xff0c;发送方发送一个数据包&#xff0c;…

游戏引擎 Unity - Unity 设置为简体中文、Unity 创建项目

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

MySQL基础-多表查询

多表查询-多表关系 多表查询-概述 例如执行下行sql语句就会出现笛卡尔积&#xff1a; select *from emp,dept; --消除笛卡尔积 select * from emp,dept where emp.dept_id dept.id; 多表查询-查询分类 多表查询-连接查询-内连接 --内连接演示 --1.查询每一个员工的姓名,及关…

[权限提升] Wdinwos 提权 维持 — 系统错误配置提权 - Trusted Service Paths 提权

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;Trusted Service Paths 提权原理 Windows 的服务通常都是以 System 权限运行的&#xff0c;所以系统在解析服务的可执行文件路径中的空格的时候也会以 System 权限进行解析&a…

【01】共识机制

BTF共识 拜占庭将军问题 拜占庭将军问题是一个共识问题 起源 Leslie Lamport在论文《The Byzantine Generals Problem》提出拜占庭将军问题。 核心描述 军中可能有叛徒&#xff0c;却要保证进攻一致&#xff0c;由此引申到计算领域&#xff0c;发展成了一种容错理论。随着…

本地部署DeepSeek教程(Mac版本)

第一步、下载 Ollama 官网地址&#xff1a;Ollama 点击 Download 下载 我这里是 macOS 环境 以 macOS 环境为主 下载完成后是一个压缩包&#xff0c;双击解压之后移到应用程序&#xff1a; 打开后会提示你到命令行中运行一下命令&#xff0c;附上截图&#xff1a; 若遇…

【Redis】Redis 经典面试题解析:深入理解 Redis 的核心概念与应用

Redis 是一个高性能的键值存储系统&#xff0c;广泛应用于缓存、消息队列、排行榜等场景。在面试中&#xff0c;Redis 是一个高频话题&#xff0c;尤其是其核心概念、数据结构、持久化机制和高可用性方案。 1. Redis 是什么&#xff1f;它的主要特点是什么&#xff1f; 答案&a…