Spring Cache + Caffeine实现本地缓存
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);
}
}
注入
方式一
新建一个枚举类
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;
}
}
注入到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失效,注解失效。
解决办法
方法用
public限定符修饰;类内部方法调用加缓存时可以用
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实现本地缓存的更多相关文章
- spring boot:使用spring cache+caffeine做进程内缓存(本地缓存)(spring boot 2.3.1)
一,为什么要使用caffeine做本地缓存? 1,spring boot默认集成的进程内缓存在1.x时代是guava cache 在2.x时代更新成了caffeine, 功能上差别不大,但后者在性能上 ...
- Spring集成GuavaCache实现本地缓存
Spring集成GuavaCache实现本地缓存: 一.SimpleCacheManager集成GuavaCache 1 package com.bwdz.sp.comm.util.test; 2 3 ...
- 使用Spring Cache + Redis + Jackson Serializer缓存数据库查询结果中序列化问题的解决
应用场景 我们希望通过缓存来减少对关系型数据库的查询次数,减轻数据库压力.在执行DAO类的select***(), query***()方法时,先从Redis中查询有没有缓存数据,如果有则直接从Red ...
- Caffeine Cache-高性能Java本地缓存组件
前面刚说到Guava Cache,他的优点是封装了get,put操作:提供线程安全的缓存操作:提供过期策略:提供回收策略:缓存监控.当缓存的数据超过最大值时,使用LRU算法替换.这一篇我们将要谈到一个 ...
- springboot之本地缓存(guava与caffeine)
1. 场景描述 因项目要使用本地缓存,具体为啥不用redis等,就不讨论,记录下过程,希望能帮到需要的朋友. 2.解决方案 2.1 使用google的guava作为本地缓存 初步的想法是使用googl ...
- JAVA缓存规范 —— 虽迟但到的JCache API与天生不俗的Spring Cache
大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 有诗云"纸上得来终觉浅,绝知 ...
- Spring Cache缓存技术的介绍
缓存用于提升系统的性能,特别适用于一些对资源需求比较高的操作.本文介绍如何基于spring boot cache技术,使用caffeine作为具体的缓存实现,对操作的结果进行缓存. demo场景 本d ...
- Spring Cache缓存框架
一.序言 Spring Cache是Spring体系下标准化缓存框架.Spring Cache有如下优势: 缓存品种多 支持缓存品种多,常见缓存Redis.EhCache.Caffeine均支持.它们 ...
- Spring Cache扩展:注解失效时间+主动刷新缓存
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 使用guava cache在本地缓存热点数据
某些热点数据在短时间内可能会被成千上万次访问,所以除了放在redis之外,还可以放在本地内存,也就是JVM的内存中. 我们可以使用google的guava cache组件实现本地缓存,之所以选择gua ...
随机推荐
- 通过redis学网络(1)-用go基于epoll实现最简单网络通信框架
本系列主要是为了对redis的网络模型进行学习,我会用golang实现一个reactor网络模型,并实现对redis协议的解析. 系列源码已经上传github https://github.com/H ...
- [汽车]车架号(VIN)的设计与规范
1 车架号概述 VIN是英文Vehicle Identification Number(车辆识别代码)的缩写,也就是我们平时所说的车架号.大架号. 总共由17位字符组成,是汽车唯一的身份识别信息,好比 ...
- 传统软件如何SaaS化改造,10个问答带你掌握最优解
摘要:如果您所在企业希望实行SaaS化改造,可访问了解华为云开发者技术团队的SaaS支持计划. 本文分享自华为云社区<[云享问答]第1期:传统软件如何SaaS化改造,10个问答带你掌握最优解!& ...
- 前端学习C语言 - 第二篇(常量、运算符、控制和循环)
常量.运算符.控制和循环 前文我们写了第一个 c 语言程序,了解了基本的数据类型.本篇将继续学习:常量.运算符.控制语句和循环语句. 常量 #define 常量 #define是用来定义常量和宏的预处 ...
- Go-变量篇
一.变量的声明方式(三种) 1.var a int = num 2.var a = num 3.a := num 二.字符类型使用细节 *Golang的字符使用UTF-8. 英文 -1 字节:汉字-3 ...
- 一站式数据可观测性平台 Datavines 正式开源啦
Datavines是一站式开源数据可观测性平台,提供元数据管理.数据概览报告.数据质量管理,数据分布查询.数据趋势洞察等核心能力,致力于帮助用户全面地了解和掌管数据,让您做到心中有数,目前作为 Dat ...
- React学习时,outlet配置(token判定,页面path监听)
尽管写过 outlet 路由的配置. 考虑到 token 判定和 路由页 变更,我不了解v6是不是有更详解的做法. 决定调一下配置,期望 在任何页面异步更新时,token 都可以在跳转前 被检测到,防 ...
- 微调用于多语言 ASR 的 MMS 适配器模型
新内容 (06/2023): 这篇博文受到 "在多语言 ASR 上微调 XLS-R" 的强烈启发,可以看作是它的改进版本. Wav2Vec2 是自动语音识别 (ASR) 的预训练模 ...
- 安装VMware Workstation 16 Pro
下载 官网:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html 注:我是在新毒霸软件管 ...
- 国产开源流批统一的数据同步工具Chunjun入门实战
@ 目录 概述 定义 特性 部署 安装 版本对应关系 通用配置详解 整体配置 Content 配置 Setting 配置 Local提交 Standalone提交 Json方式使用 SQL方式使用 M ...