New file |
| | |
| | | package com.ruoyi.account.wx.tools; |
| | | |
| | | 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<T> implements WxCacheTemplate<T> { |
| | | /** |
| | | * 缓存环境 |
| | | */ |
| | | private String env = "wx"; |
| | | |
| | | /** |
| | | * 本地缓存实例 |
| | | */ |
| | | private LoadingCache<String, Object> 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 <T> |
| | | * @return |
| | | */ |
| | | private static <T> LoadingCache<String, T> caffineCacheManage(WxCache cache) { |
| | | log.info("初始化缓存的实体数据:{}", cache); |
| | | if (Objects.isNull(cache)) { |
| | | throw new NullPointerException("请实例化一个Cache对象!"); |
| | | } |
| | | LoadingCache<String, T> 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<String, T>() { |
| | | @Override |
| | | public void onRemoval(String key, Object value, RemovalCause cause) { |
| | | log.info(key + ":" + value + ":" + cause.name()); |
| | | } |
| | | }) |
| | | // build里面要实现一个匿名抽象类 |
| | | .build(new CacheLoader<String, T>() { |
| | | // 这个方法是默认的数据加载实现,get的时候,如果key没有对应的值,就调用这个方法进行加载。此处是没有默认值则返回null |
| | | @Override |
| | | public T load(String key) throws Exception { |
| | | return null; |
| | | } |
| | | }); |
| | | return localcache; |
| | | } |
| | | } |