赞
踩
在上篇博文中,我使用了guava作为spring的本地缓存,来实现在加载数据到本地的需求。在这个篇博文中,我将记录总结使用caffeine作为本地缓存。在spring5后,spring官方放弃了guava,而使用了性能更优秀的caffeine,本篇将结合springboot2.x来实现caffeine的使用。了解有关caffeine的详细内容请见caffeine。
同样,本篇也采用的是手动配置参数类,没有使用springboot的自动配置。首先是创建配置属性类CacheProperties。
@ConfigurationProperties(prefix = "spring.cache")
public class CacheProperties {
private int initialCapacity; //初始缓存空间大小
private long maximnumSize; //缓存的最大条数
private long maximunmWeight; //缓存的最大权重
private long expireAfterAccess; //最后一次写入或访问后经过固定的时间过期
private long expireAfterWrite; //最后一次写入后经过固定的时间过期
private long refreshAfterWrite; //写入后经过固定的时间刷新缓存
private boolean weakKeys; // key为弱引用
private boolean weakValues; // value为弱引用
private boolean softValues; //value 为软引用
private boolean recordStats; //统计功能
....//省略getter setter方法
}
创建自定义CacheLoader类,在配置cache或CacheManager时如果配置了refreshAfterWrite属性,就必须指定一个CacheLoader。
public class CacheLoadCustom implements CacheLoader{ @Override public Object load(Object o) throws Exception { if (o.toString().equalsIgnoreCase("hello")) { Thread.sleep(3000); return o.toString(); } else if (o.toString().equalsIgnoreCase("world")) { Thread.sleep(5000); return o.toString(); } return o.toString(); } @Override public Object reload(Object key, Object oldValue) throws Exception { if (key.toString().equalsIgnoreCase("hello")) { return "world"; } else if (key.toString().equalsIgnoreCase("world")) { return "hello"; } return "no value"; } }
创建配置类CacheConfig类,在配置CacheManager类,指定Caffeine对象。关于CacheLoader的指定,可以在创建Caffeine时指定,也可以在配置CacheManager时指定。当缓存不存在时,会根据CacheLoader的load方法进行加载,所以自定义CacheLoader的参数和返回值都是Object。
@EnableConfigurationProperties(CacheProperties.class) @Configuration public class CacheConfig { @Autowired private CacheProperties cacheProperties; @Bean("cacheLoader") public CacheLoadCustom cacheLoadCustom(){ return new CacheLoadCustom(); } @Bean("cacheCaffeine") public Caffeine caffeine(){ Caffeine caffeine = Caffeine.newBuilder().maximumSize(cacheProperties.getMaximnumSize()); caffeine.initialCapacity(cacheProperties.getInitialCapacity()); caffeine.refreshAfterWrite(cacheProperties.getRefreshAfterWrite(), TimeUnit.SECONDS); caffeine.expireAfterWrite(cacheProperties.getExpireAfterWrite(), TimeUnit.SECONDS); return caffeine; } @Bean public CacheManager cacheManager(@Qualifier("cacheLoader") CacheLoadCustom cacheLoadCustom, @Qualifier("cacheCaffeine") Caffeine caffeine){ CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); caffeineCacheManager.setCacheLoader(cacheLoadCustom); caffeineCacheManager.setCaffeine(caffeine); return caffeineCacheManager; } }
@RestController public class HelloAction { @Autowired private CacheManager cacheManager; @RequestMapping("/hello") public String hello(){ long start = System.currentTimeMillis(); String res = cacheManager.getCache("hello").get("hello").get().toString(); long end = System.currentTimeMillis(); return res + " wait time " + (end - start); } @RequestMapping("/world") public String world(){ long start = System.currentTimeMillis(); String res = cacheManager.getCache("world").get("world").get().toString(); long end = System.currentTimeMillis(); return res + " wait time " + (end - start); } }
这里,我只简单的配置使用了caffeine,仅实现了通过cacheloader进行缓存的加载和过期缓存的更新。关于caffeine的其他特性,如驱逐策略,异步加载等没有体现。
参考资料:
https://www.jianshu.com/p/c72fb0c787fc
https://blog.csdn.net/xiaolyuh123/article/details/78794012
源码地址:
https://github.com/Edenwds/springboot_study/tree/master/caffeine
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。