网站首页 > java教程 正文
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);
}
}
猜你喜欢
- 2024-10-25 Caffeine高性能本地缓存框架初探(caffeine缓存原理)
- 2024-10-25 Redis学习3——Redis应用之缓存(redis的缓存的使用方式)
- 2024-10-25 Java高级——缓存的使用场景(java缓存机制)
- 2024-10-25 java中常用的几种缓存类型介绍(java常用缓存技术)
- 2024-10-25 本地缓存之王caffeine#代码(本地缓存 js)
- 2024-10-25 skywalking agent 本地缓存队列参数设置
- 2024-10-25 史上最实用的:分布式缓存方案(分布式缓存设计方案)
- 2024-10-25 使用Guava作为本地缓存让系统飞起来
- 2024-10-25 深究分布式缓存的九个点(分布式缓存技术有哪些)
- 2024-10-25 面试题之java缓存总结,从单机缓存到分布式缓存架构
你 发表评论:
欢迎- 最近发表
-
- pyinstaller打包python程序高级技巧
- 将python打包成exe的方式(python打包成exe的方法)
- Python打包:如何将 Flask 项目打包成exe程序
- py2exe实现python文件打包为.exe可执行程序(上篇)
- 如何将 Python 项目打包成 exe,另带卸载功能!
- Python打包成 exe,太大了该怎么解决?
- 可视化 Python 打包 exe,这个神器绝了!
- 案例详解pyinstaller将python程序打包为可执行文件exe
- Cocos 3.x 菜鸟一起玩:打包window程序
- 怎么把 Python + Flet 开发的程序,打包为 exe ?这个方法很简单!
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)