package com.jilongda.applet.wx.utils; import com.github.benmanes.caffeine.cache.*; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @author xiaochen * @ClassName AbstractCaffineCache * @Description * @date 2021-01-11 11:27 */ @Slf4j class WxCaffineCache implements WxCacheTemplate { /** * 缓存环境 */ private String env = "wx"; /** * 本地缓存实例 */ private LoadingCache loadingCache; /** * 构造函数 * */ public WxCaffineCache() { WxCache cache = WxCache.options().setTimeUnit(TimeUnit.SECONDS).build(); // 构建本地缓存实例 this.loadingCache = caffineCacheManage(cache); } @Override public boolean setKey(String key, T value) { if (Objects.isNull(this.loadingCache)) { return Boolean.FALSE; } if (StringUtils.hasLength(this.env)) { this.loadingCache.put(this.env + ":" + key, value); } else { this.loadingCache.put(key, value); } return Boolean.TRUE; } @Override public T getKey(String key) { if (Objects.isNull(this.loadingCache)) { return null; } try { if (StringUtils.hasLength(this.env)) { return (T) this.loadingCache.get(this.env + ":" + key); } else { return (T) this.loadingCache.get(key); } } catch (Exception e) { return null; } } @Override public boolean delKey(String key) { if (Objects.isNull(this.loadingCache)) { return Boolean.FALSE; } if (StringUtils.hasLength(this.env)) { this.loadingCache.invalidate(this.env + ":" + key); } else { this.loadingCache.invalidate(key); } return Boolean.TRUE; } /** * 缓存管理 * * @param cache * @param * @return */ private static LoadingCache caffineCacheManage(WxCache cache) { log.info("初始化缓存的实体数据:{}", cache); if (Objects.isNull(cache)) { throw new NullPointerException("请实例化一个Cache对象!"); } LoadingCache localcache = // 构建本地缓存,调用链的方式 // ,1000是设置缓存的初始化容量,maximumSize是设置缓存最大容量,当超过了最大容量,guava将使用LRU算法(最少使用算法),来移除缓存项 // expireAfterAccess(12,TimeUnit.HOURS)设置缓存有效期为12个小时 Caffeine.newBuilder().initialCapacity(cache.getInitialCapacity()).maximumSize(cache.getMaximumSize()) // 设置写缓存后n秒钟过期 // .expireAfterWrite(30, TimeUnit.SECONDS) .expireAfterWrite(cache.getDuration(), cache.getTimeunit()) // 设置读写缓存后n秒钟过期,实际很少用到,类似于expireAfterWrite //.expireAfterAccess(googleCache.getDuration(), googleCache.getTimeunit()) // 只阻塞当前数据加载线程,其他线程返回旧值 //.refreshAfterWrite(10, TimeUnit.SECONDS) // 设置缓存的移除通知//用户手动移除EXPLICIT, // //用户手动替换REPLACED,//被垃圾回收COLLECTED,//超时过期EXPIRED,//SIZE由于缓存大小限制 .removalListener(new RemovalListener() { @Override public void onRemoval(String key, Object value, RemovalCause cause) { log.info(key + ":" + value + ":" + cause.name()); } }) // build里面要实现一个匿名抽象类 .build(new CacheLoader() { // 这个方法是默认的数据加载实现,get的时候,如果key没有对应的值,就调用这个方法进行加载。此处是没有默认值则返回null @Override public T load(String key) throws Exception { return null; } }); return localcache; } }