文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring内存缓存Caffeine如何使用

2023-07-05 16:11

关注

这篇文章主要讲解了“Spring内存缓存Caffeine如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring内存缓存Caffeine如何使用”吧!

项目配置

依赖

首先搭建一个标准的SpringBoot项目工程,相关版本以及依赖如下

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

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

使用实例

引入上面的jar包之后,就可以进入caffeine的使用环节了;我们主要依照官方wiki来进行演练

Home zh CN &middot; ben-manes/caffeine Wiki

caffeine提供了四种缓存策略,主要是基于手动添加/自动添加,同步/异步来进行区分

其基本使用姿势于Guava差不多

1.手动加载

private LoadingCache<String, Integer> autoCache;private AtomicInteger idGen;public CacheService() {      // 手动缓存加载方式      idGen = new AtomicInteger(100);      uidCache = Caffeine.newBuilder()              // 设置写入后五分钟失效              .expireAfterWrite(5, TimeUnit.MINUTES)              // 设置最多的缓存数量              .maximumSize(100)              .build();}

1.1 三种失效策略

注意参数设置,我们先看一下失效策略,共有下面几种

权重:

时间:

引用:

弱引用:这允许在GC的过程中,当没有被任何强引用指向的时候去将缓存元素回收

软引用:在GC过程中被软引用的对象将会被通过LRU算法回收

1.2 缓存增删查姿势

接下来我们看一下手动方式的使用

public void getUid(String session) {    // 重新再取一次,这次应该就不是重新初始化了    Integer uid = uidCache.getIfPresent(session);    System.out.println("查看缓存! 当没有的时候返回的是 uid: " + uid);    // 第二个参数表示当不存在时,初始化一个,并写入缓存中    uid = uidCache.get(session, (key) -> 10);    System.out.println("初始化一个之后,返回的是: " + uid);    // 移除缓存    uidCache.invalidate(session);    // 手动添加一个缓存    uidCache.put(session + "_2", 11);    // 查看所有的额缓存    Map map = uidCache.asMap();    System.out.println("total: " + map);    // 干掉所有的缓存    uidCache.invalidateAll();}

查询缓存&添加缓存

添加缓存

清空缓存

执行完毕之后,输出日志:

查看缓存! 当没有的时候返回的是 uid: null
初始化一个之后,返回的是: 10
total: {02228476-bcd9-412d-b437-bf0092c4a5f6_2=11}

2.自动加载

在创建的时候,就指定缓存未命中时的加载规则

// 在创建时,自动指定加载规则private LoadingCache<String, Integer> autoCache;private AtomicInteger idGen;public CacheService() {    // 手动缓存加载方式    idGen = new AtomicInteger(100);    autoCache = Caffeine.newBuilder()            .expireAfterWrite(5, TimeUnit.MINUTES)            .maximumSize(100)            .build(new CacheLoader<String, Integer>() {                @Override                public @Nullable Integer load(@NonNull String key) throws Exception {                    return idGen.getAndAdd(1);                }            });}

它的配置,与前面介绍的一致;主要的区别点在于build时,确定缓存值的获取方式

2.1 缓存使用姿势

public void autoGetUid(String session) {    Integer uid = autoCache.getIfPresent(session);    System.out.println("自动加载,没有时返回: " + uid);    uid = autoCache.get(session);    System.out.println("自动加载,没有时自动加载一个: " + uid);    // 批量查询    List<String> keys = Arrays.asList(session, session + "_1");    Map<String, Integer> map = autoCache.getAll(keys);    System.out.println("批量获取,一个存在一个不存在时:" + map);    // 手动加一个    autoCache.put(session + "_2", 11);    Map total = autoCache.asMap();    System.out.println("total: " + total);}

与前面的区别在于获取缓存值的方式

实际输出结果如下

自动加载,没有时返回: null
自动加载,没有时自动加载一个: 100
批量获取,一个存在一个不存在时:{02228476-bcd9-412d-b437-bf0092c4a5f6=100, 02228476-bcd9-412d-b437-bf0092c4a5f6_1=101}
total: {02228476-bcd9-412d-b437-bf0092c4a5f6_2=11, 02228476-bcd9-412d-b437-bf0092c4a5f6_1=101, 02228476-bcd9-412d-b437-bf0092c4a5f6=100}

3.异步手动加载

异步,主要是值在获取换粗内容时,采用的异步策略;使用与前面没有什么太大差别

// 手动异步加载缓存private AsyncCache<String, Integer> asyncUidCache;public CacheService() {    asyncUidCache = Caffeine.newBuilder()            .expireAfterWrite(5, TimeUnit.MINUTES)            .maximumSize(100)            .buildAsync();}

3.1 缓存使用姿势

public void asyncGetUid(String session) throws ExecutionException, InterruptedException {    // 重新再取一次,这次应该就不是重新初始化了    CompletableFuture<Integer> uid = asyncUidCache.getIfPresent(session);    System.out.println("查看缓存! 当没有的时候返回的是 uid: " + (uid == null ? "null" : uid.get()));    // 第二个参数表示当不存在时,初始化一个,并写入缓存中    uid = asyncUidCache.get(session, (key) -> 10);    System.out.println("初始化一个之后,返回的是: " + uid.get());    // 手动塞入一个缓存    asyncUidCache.put(session + "_2", CompletableFuture.supplyAsync(() -> 12));    // 移除缓存    asyncUidCache.synchronous().invalidate(session);    // 查看所有的额缓存    System.out.println("print total cache:");    for (Map.Entry<String, CompletableFuture<Integer>> sub : asyncUidCache.asMap().entrySet()) {        System.out.println(sub.getKey() + "==>" + sub.getValue().get());    }    System.out.println("total over");}

与前面相比,使用姿势差不多,唯一注意的是,获取的并不是直接的结果,而是CompletableFuture,上面执行之后的输出如下:

查看缓存! 当没有的时候返回的是 uid: null
初始化一个之后,返回的是: 10
print total cache:
5dd53310-aec7-42a5-957e-f7492719c29d_2==>12
total over

4.异步自动加载

在定义缓存时,就指定了缓存不存在的加载逻辑;与第二个相比区别在于这里是异步加载数据到缓存中

private AtomicInteger idGen;// 自动异步加载缓存private AsyncLoadingCache<String, Integer> asyncAutoCache;public CacheService() {  idGen = new AtomicInteger(100);  asyncAutoCache = Caffeine.newBuilder()            .expireAfterWrite(5, TimeUnit.MINUTES)            .maximumSize(100)            .buildAsync(new CacheLoader<String, Integer>() {                @Override                public @Nullable Integer load(@NonNull String key) throws Exception {                    return idGen.getAndAdd(1);                }            });}

4.1 缓存使用姿势

public void asyncAutoGetUid(String session) {    try {        CompletableFuture<Integer> uid = asyncAutoCache.getIfPresent(session);        System.out.println("自动加载,没有时返回: " + (uid == null ? "null" : uid.get()));        uid = asyncAutoCache.get(session);        System.out.println("自动加载,没有时自动加载一个: " + uid.get());        // 批量查询        List<String> keys = Arrays.asList(session, session + "_1");        CompletableFuture<Map<String, Integer>> map = asyncAutoCache.getAll(keys);        System.out.println("批量获取,一个存在一个不存在时:" + map.get());                // 手动加一个        asyncAutoCache.put(session + "_2", CompletableFuture.supplyAsync(() -> 11));                // 查看所有的额缓存        System.out.println("print total cache:");        for (Map.Entry<String, CompletableFuture<Integer>> sub : asyncAutoCache.asMap().entrySet()) {            System.out.println(sub.getKey() + "==>" + sub.getValue().get());        }        System.out.println("total over");        // 清空所有缓存        asyncAutoCache.synchronous().invalidateAll();      } catch (Exception e) {        e.printStackTrace();    }}

输出:

自动加载,没有时返回: null
自动加载,没有时自动加载一个: 102
批量获取,一个存在一个不存在时:{5dd53310-aec7-42a5-957e-f7492719c29d=102, 5dd53310-aec7-42a5-957e-f7492719c29d_1=103}
print total cache:
5dd53310-aec7-42a5-957e-f7492719c29d_2==>11
5dd53310-aec7-42a5-957e-f7492719c29d_1==>103
5dd53310-aec7-42a5-957e-f7492719c29d==>102
total over

感谢各位的阅读,以上就是“Spring内存缓存Caffeine如何使用”的内容了,经过本文的学习后,相信大家对Spring内存缓存Caffeine如何使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯