Caffeine简介

Caffeine是一个高性能,高命中率,低内存占用,near optimal 的本地缓存,简单来说它是 Guava Cache 的优化加强版

依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
   <groupId>com.github.ben-manes.caffeine</groupId>
   <artifactId>caffeine</artifactId>
</dependency>

开启缓存

@EnableCaching注解开启使用缓存管理功能

@SpringBootApplication
@EnableCaching
public class Application {

   public static void main(String[] args) {
       SpringApplication.run(Application.class, args);
  }

}

注入

方式一

  1. 新建一个枚举类

public enum Caches {
   CACHE_ACCESS_TOKEN(10, 7200);

   /** 最大数量 */
   private Integer maxSize;

   /** 过期时间 秒 */
   private Integer ttl;

   Caches() {
  }

   Caches(Integer maxSize, Integer ttl) {
       this.maxSize = maxSize;
       this.ttl = ttl;
  }

   public Integer getMaxSize() {
       return maxSize;
  }

   public Integer getTtl() {
       return ttl;
  }

}
  1. 注入到IOC容器

    /**
    * 本地缓存
    * @return
    */
   @Bean
   @Primary
   public CacheManager cacheManager() {
       SimpleCacheManager simpleCacheManager = new SimpleCacheManager();

       ArrayList<CaffeineCache> caffeineCaches = new ArrayList<>();

       for (Caches c : Caches.values()) {
           caffeineCaches.add(new CaffeineCache(c.name(),
                           Caffeine.newBuilder()
                                  .recordStats()
                                  .expireAfterWrite(c.getTtl(), TimeUnit.SECONDS)
                                  .maximumSize(c.getMaxSize())
                                  .build()
                  )
          );
      }

       simpleCacheManager.setCaches(caffeineCaches);
       return simpleCacheManager;

  }

方式二

@Bean
@Primary
public CacheManager cacheManager() {

   CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
   Caffeine<Object, Object> caffeine = Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.MINUTES);
   caffeineCacheManager.setCaffeine(caffeine);
   return caffeineCacheManager;

}

使用

可以使用spring提供的@Cacheable、@CachePut、@CacheEvict等注解来方便的使用caffeine缓存

@Cacheable(cacheNames = "CACHE_ACCESS_TOKEN", key = "#root.methodName")
public String getAccessToken(String corpid, String corpsecret) {

  //todo something...
  return "";

}

问题

使用@Cacheable缓存不起作用

失效场景

  • 在私有方法上加缓存

  • 类内部方法调用加缓存

失效原因

Spring cache 的实现原理是基于 AOP 的动态代理实现的:即都在方法调用前后去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。

AOP 不支持对 private 私有方法的拦截,所以也就不支持私有方法上的 Spring Cache 注解。

this 调用不是代理对象的调用, 所以 AOP 失效,注解失效。

解决办法

  1. 方法用 public 限定符修饰;

  2. 类内部方法调用加缓存时可以用 SpringContextUtil 获取当前 Bean ,由它来调用

工具类

SpringContextUtil

@Component
public class SpringContextUtil implements ApplicationContextAware {

   public static ApplicationContext applicationContext;

   public void setApplicationContext(ApplicationContext applicationContext) {
       SpringContextUtil.applicationContext = applicationContext;
  }

   public static Object getBean(String name) {
       return applicationContext.getBean(name);
  }

   public static <T> T getBean(Class<T> clazz) {
       return applicationContext.getBean(clazz);
  }

   public static <T> T getBean(String name, Class<T> clazz) {
       return applicationContext.getBean(name, clazz);
  }

   public static Boolean containsBean(String name) {
       return applicationContext.containsBean(name);
  }

   public static Boolean isSingleton(String name) {
       return applicationContext.isSingleton(name);
  }

   public static Class<? extends Object> getType(String name) {
       return applicationContext.getType(name);
  }


}
 

Spring Cache + Caffeine实现本地缓存的更多相关文章

  1. spring boot:使用spring cache+caffeine做进程内缓存(本地缓存)(spring boot 2.3.1)

    一,为什么要使用caffeine做本地缓存? 1,spring boot默认集成的进程内缓存在1.x时代是guava cache 在2.x时代更新成了caffeine, 功能上差别不大,但后者在性能上 ...

  2. Spring集成GuavaCache实现本地缓存

    Spring集成GuavaCache实现本地缓存: 一.SimpleCacheManager集成GuavaCache 1 package com.bwdz.sp.comm.util.test; 2 3 ...

  3. 使用Spring Cache + Redis + Jackson Serializer缓存数据库查询结果中序列化问题的解决

    应用场景 我们希望通过缓存来减少对关系型数据库的查询次数,减轻数据库压力.在执行DAO类的select***(), query***()方法时,先从Redis中查询有没有缓存数据,如果有则直接从Red ...

  4. Caffeine Cache-高性能Java本地缓存组件

    前面刚说到Guava Cache,他的优点是封装了get,put操作:提供线程安全的缓存操作:提供过期策略:提供回收策略:缓存监控.当缓存的数据超过最大值时,使用LRU算法替换.这一篇我们将要谈到一个 ...

  5. springboot之本地缓存(guava与caffeine)

    1. 场景描述 因项目要使用本地缓存,具体为啥不用redis等,就不讨论,记录下过程,希望能帮到需要的朋友. 2.解决方案 2.1 使用google的guava作为本地缓存 初步的想法是使用googl ...

  6. JAVA缓存规范 —— 虽迟但到的JCache API与天生不俗的Spring Cache

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 有诗云"纸上得来终觉浅,绝知 ...

  7. Spring Cache缓存技术的介绍

    缓存用于提升系统的性能,特别适用于一些对资源需求比较高的操作.本文介绍如何基于spring boot cache技术,使用caffeine作为具体的缓存实现,对操作的结果进行缓存. demo场景 本d ...

  8. Spring Cache缓存框架

    一.序言 Spring Cache是Spring体系下标准化缓存框架.Spring Cache有如下优势: 缓存品种多 支持缓存品种多,常见缓存Redis.EhCache.Caffeine均支持.它们 ...

  9. Spring Cache扩展:注解失效时间+主动刷新缓存

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  10. 使用guava cache在本地缓存热点数据

    某些热点数据在短时间内可能会被成千上万次访问,所以除了放在redis之外,还可以放在本地内存,也就是JVM的内存中. 我们可以使用google的guava cache组件实现本地缓存,之所以选择gua ...

随机推荐

  1. 00.XML入门

    0.了解XML Extensible Markup Language 可扩展标记语言 申明信息不算元素,左图中book为根元素,根元素有且仅有一个; 1.初识XML 1.3用IDE创建xml(以ecl ...

  2. Python 日期和时间函数使用指南

    在本教程中,我们将介绍 python 的 datetime 模块以及如何使用它来处理日期.时间,以及日期时间的格式化处理.它包含各种实用示例,可帮助您通过 python 函数更加快捷高效进行日期和时间 ...

  3. 国际顶刊《PNAS》:爱发朋友圈的人,更容易长寿

    点上面关注我们,每日获取前沿新知 近几十年来,智能手机和网络的普及率越来越高,与此同时,"朋友圈"应运而生. 在这个朋友圈里,有人十分活跃,而也有些人是"国家级潜水运动员 ...

  4. DASCTF二进制专项部分Writeup

    easynote create:堆大小可以任意分配只要不超过0xFFF create()  unsigned __int64 create() { int i; // [rsp+0h] [rbp-20 ...

  5. ENVI5.3 安装教程,新手入门(超详细)附安装包和常见问题

    ENVI是一个完整的遥感图像处理平台,广泛应用于科研.环境保护.气象.农业.林业.地球科学.遥感工程.水利.海洋等领域.目前ENVI已成为遥感影像处理的必备软件,包含辐射定标.大气校正.镶嵌裁剪.分类 ...

  6. P1751 贪吃虫 题解

    题意: 题目传送门 在一棵 n 个结点的树上,有 k 个贪吃虫去吃食物. 每个贪吃虫都走到达食物的唯一路径. 当一条贪吃虫通向食物的道路上有另一条贪吃虫,则较远的那只停止移动. 多条贪吃虫要进入同一节 ...

  7. CKS 考试题整理 (03)-kube-bench 修复不安全项

    Context 针对 kubeadm 创建的 cluster 运行 CIS 基准测试工具时,发现了多个必须立即解决的问题. Task 通过配置修复所有问题并重新启动受影响的组件以确保新的设置生效. 修 ...

  8. 保护数据隐私:深入探索Golang中的SM4加密解密算法

    前言 最近做的项目对安全性要求比较高,特别强调:系统不能涉及MD5.SHA1.RSA1024.DES高风险算法. 那用什么嘞?甲方:建议用国产密码算法SM4. 擅长敏捷开发(CV大法)的我,先去Git ...

  9. 【技术积累】Mysql中的SQL语言【一】

    建表语句 后续所有内容建立在这些SQL语句上 CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), age INT ); CREATE ...

  10. ##Can not deserialize instance of java.lang.String out of START_OBJECT token

    请求中定义了一个String字段,该字段主要是一个JSON Object字符串,对应的Java PO的相关字段类型是String. 但是测试的时候传的参数是JSON对象,例如{"aa&quo ...