java缓存系列----caffein

398 阅读3分钟

1:caffein 缓存介绍

      Caffeine是一个基于Java8开发的提供了[近乎最佳]命中率的[高性能]的缓存库。

缓存和ConcurrentMap]有点相似,但还是有所区别。最根本的区别是[ConcurrentMap]将会持有所有加入到缓存当中的元素,直到它们被从缓存当中手动移除。但是,Caffeine的缓存Cache 通常会被配置成自动驱逐缓存中元素,以限制其内存占用。在某些场景下,LoadingCacheAsyncLoadingCache 因为其自动加载缓存的能力将会变得非常实用;

    以上是对 Caffeine 的介绍,其实在平时的开发中我们也可以在代码中使用 HashMap 作为我们的本地缓存,大部分场景下使用 HashMap 来缓存也够用,但是它不够灵活。

    如以下细节点需要处理:

       1: 当需要缓存的数据量过大,导致内存溢出   如何处理

       2:只需要缓存一小段时间,过期后从库(或其他系统中)中实时获取再更新到缓存中

       3:不同的场景需要不同的策略(如不同的过期时间,不同的缓存最大量   这样自己通过hashMap 去实现就变得比较复杂)

   2: 手动使用Caffeine

     你在项目中可以直接手动创建  Caffeine  缓存,再进行手动的操作,具体使用如下:

@Bean(name = "manualCache")  
public Cache<Object, Object> manualCache() {  
Cache<Object, Object> build = Caffeine.newBuilder()  
.expireAfterWrite(60, TimeUnit.SECONDS)  
.initialCapacity(100)  
.maximumSize(500)  
.build();  
return build;  
} 

    这里将其声明成一个spring   Bean   对象,后续使用中你可以直接注入的方式使用该bean, 或者可以直接在一个类中写一个静态方法返回Cache即可;

     Caffeine几个参数的说明:

参数描述
initialCapacity=[integer]初始的缓存空间大小(比较常用)
maximumSize=[long]缓存的最大条数 (比较常用)
maximumWeight=[long]缓存的最大权重
expireAfterAccess=[duration]最后一次写入或访问后经过固定时间过期 (比较常用)
expireAfterWrite=[duration]最后一次写入后经过固定时间过期(比较常用)
refreshAfterWrite=[duration]创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存 refreshAfterWrite requires a LoadingCache
weakKeys打开 key 的弱引用
weakValues打开 value 的弱引用
softValues打开 value 的软引用
recordStats开发统计功能
------

   3: 自动注入Caffeine集成springboot cache

这里需要说明的一点: jdk1.8 仅支持 Caffeine 3以下的版本 在项目的Application 启动类中指定开启缓存 加上@EnableCaching 注解

@SpringBootApplication  
@EnableCaching  
public class TestApplication {  
  
public static void main(String[] args) {  
SpringApplication.run(TestApplication.class, args);  
}  
}

在缓存配置类中声明 缓存管理器类 可以自定义声明多个缓存管理器,按照业务实现的需要来进行声明 如声明两个不同的缓存管理器: 1:defaultCacheManager 默认使用

@Bean(name = "defaultCacheManager")  
@Primary  
public CacheManager cacheManager() {  
CaffeineCacheManager cacheManager = new CaffeineCacheManager();  
cacheManager.setCaffeine(Caffeine.newBuilder()  
// 设置最后一次写入或访问后经过固定时间过期  
.expireAfterAccess(600, TimeUnit.SECONDS)  
// 初始的缓存空间大小  
.initialCapacity(100)  
// 缓存的最大条数  
.maximumSize(500));  
return cacheManager;  
}

2:specCacheManager特定使用

@Bean(name = "specCacheManager")  
public CacheManager specCacheManager() {  
CaffeineCacheManager cacheManager = new CaffeineCacheManager();  
cacheManager.setCaffeine(Caffeine.newBuilder()  
// 设置最后一次写入或访问后经过固定时间过期  
.expireAfterAccess(4, TimeUnit.SECONDS)  
// 初始的缓存空间大小  
.initialCapacity(100)  
// 缓存的最大条数  
.maximumSize(500));  
return cacheManager;  
}

缓存的使用: 在 spring 类中使用缓存就很简单了,直接声明该方法 @Cacheable 注解

@Cacheable(value = "CaffeineService:getUser",cacheManager = "defaultCacheManager",key="#id")  
public String getUser(Long id){  
System.out.println("没有走缓存获取到数据");  
return "beppe"+id;  
}
@Cacheable(value = "CaffeineService:getCity",cacheManager = "specCacheManager",key="#name")  
public String getCity(String name){  
System.out.println("没有走缓存获取到数据");  
return "shanghaibeppe"+name;  
}

注解里的几个参数说明: value 指定缓存的名称,可以理解成 不同缓存对应一个HashMap 一般一个方法对应一个缓存名,使用 类名+方法 名 cacheManager 具体使用那个缓存管理器,@Configuration 缓存配置类中声明的具体缓存管理器 key 根据该key 来存以及取缓存,可以理解成HashMap 的key