java缓存——(二) Caffeine缓存CacheManager与配置文件
Spring boot Caffeine缓存(一)——CacheManager与配置文件
Spring boot Caffeine缓存(二)——Cache、LoadingCache
Spring boot Caffeine缓存(三)——使用注解
spring5(springboot2)开始用Caffeine取代guava,至于其性能对比可以参考Caffeine给的测试结果各缓存性能对比。
这里贴出一个读写的对比
Caffeine在springboot中集成非常简单,可以通过配置文件来设置
spring: cache: cache-names: outLimit,notOutLimit caffeine: spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s,refreshAfterWrite=7s type: caffeine
这种方法设置的简单,但是灵活性不够高,如上边设置的cache(cache name)所有的规则都是一样的。这块我没深入研究,不多做介绍。
也可以通过代码配置
左边这块是我在看Caffeine时做的一些配置。这些东西很多,我可能会分多篇文章来讲。
先来说下最常用的CacheManager
CacheManager
CacheManager的使用场景比较多,最常见的@Cacheable、@CachePut、@CacheEvict等默认都可以配合CacheManager使用。
先看下我集成的三个CacheManager
@Value("${caffeine.spec}") private String caffeineSpec; @Autowired private CacheLoader cacheLoader; @Bean public CacheManager cacheManagerWithCacheLoading(){ logger.info("cacheManagerWithCacheLoading" ); Caffeine caffeine = Caffeine.newBuilder() .initialCapacity(100) .maximumSize(1000) // .refreshAfterWrite(5,TimeUnit.SECONDS) .expireAfterWrite(50,TimeUnit.SECONDS); CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setAllowNullValues(true); cacheManager.setCaffeine(caffeine); // cacheManager.setCacheLoader(cacheLoader); cacheManager.setCacheNames(getNames()); return cacheManager; } @Bean(name = "caffeine") @Primary public CacheManager cacheManagerWithCaffeine(){ logger.info("This is cacheManagerWithCaffeine"); CaffeineCacheManager cacheManager = new CaffeineCacheManager(); Caffeine caffeine = Caffeine.newBuilder() //cache的初始容量值 .initialCapacity(100) //maximumSize用来控制cache的最大缓存数量,maximumSize和maximumWeight不可以同时使用, .maximumSize(1000); //控制最大权重 // .maximumWeight(100); // .expireAfter(); //使用refreshAfterWrite必须要设置cacheLoader // .refreshAfterWrite(5,TimeUnit.SECONDS); cacheManager.setCaffeine(caffeine); // cacheManager.setCacheLoader(cacheLoader); cacheManager.setCacheNames(getNames()); // cacheManager.setAllowNullValues(false); return cacheManager; } @Bean(name = "caffeineSpec") public CacheManager cacheManagerWithCaffeineFromSpec(){ CaffeineSpec spec = CaffeineSpec.parse(caffeineSpec); Caffeine caffeine = Caffeine.from(spec); //此方法等同于上面from(spec) // Caffeine caffeine = Caffeine.from(caffeineSpec); CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(caffeine); cacheManager.setCacheNames(getNames()); return cacheManager; } private static List<String> getNames(){ List<String> names = new ArrayList<>(2); names.add("outLimit"); names.add("notOutLimit"); return names; }
CacheLoader会在后面介绍,它是cache的一种加载策略,key不存在或者key过期之类的都可以通过CacheLoader来获得/重新获得数据。
cacheManagerWithCaffeine这个bean是以Caffeine为基础来设置一个CacheManager。如果设置refreshAfterWrite的话后边必须要设置cacheLoader。如果不设置的话,项目启动的时候会抛异常。
这里有个setCacheNames,主要是用来创建多个cache的,但是多个cache使用相同的策略。
cacheManagerWithCacheLoading这个bean是创建了一个带有CacheLoader的bean。它跟cacheManagerWithCaffeine这块的主要区别是,最初我在cacheManagerWithCaffeine里只是想创建一个简单的key-value存储,没有CacheLoader模块,所以cacheManagerWithCaffeine这个bean如果里边的key过期或不存在cache中是获取不到数据的,直接返回null。但是cacheManagerWithCacheLoading不同,如果key过期或不存在会从他的CacheLoader策略里重新加载数据。
cacheManagerWithCaffeineFromSpec是通过spec来创建cacheManager。
先看下面两行代码
CaffeineSpec spec = CaffeineSpec.parse(caffeineSpec); Caffeine caffeine = Caffeine.from(spec);
caffeineSpec这里是从配置文件中获取的配置,如配置文件设置如下
caffeine: spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s
caffeineSpec是个符合其规则的字符串。
进入其源码
@SuppressWarnings("StringSplitter") public static CaffeineSpec parse(String specification) { CaffeineSpec spec = new CaffeineSpec(specification); for (String option : specification.split(SPLIT_OPTIONS)) { spec.parseOption(option.trim()); } return spec; }
可以看到其处理方式,非常简单。
Caffeine caffeine = Caffeine.from(spec);这行就是加载spec中的信息,自己点击下就知道什么意思了。
代码中写了很多注释,这里不多做解释了,如果有不明白的可以留言,或者在后边我会介绍其它块的时候点出。
代码的github地址Caffeine。这只是我自己摸索的时候写的,有些不太规范,仅供大家参考。
---------------------
原文:https://blog.csdn.net/qq_35981283/article/details/82354081