使用Guava 缓存的一次重构
前端时间看了一个guava教程, 然后项目中正好用到一个缓存的场景,于是用它的缓存重构了原来的代码。
背景
业务背景如下:有一个配置项rootStaff,一个耗时的运算从rootStaff下拿到一堆关联的staff,得到一个staffList。rootStaff可配置可更改,staffList可能会因为员工入职离职而变化,所以每天要更新一下计算结果。
根据以上业务背景,我们需要缓存rootStaff和staffList, 如果rootStaff和缓存不一样或者时间过期了就需要重新计算。
Guava缓存简析
guava缓存主要参考了这篇文章,这里就不再复述。
实现
在设计怎么构造和调用缓存时我还是想把它写成一个缓存工具类和一个业务类,虽然目前还没有第二个地方调用工具类,只是那样看上去会更清晰一些。
对缓存工具类,由于我想做成更业务无关些,所以打算采用get(K, Callable<V>)
方法而不是build时候传入方法。然后缓存策略默认写死一天过期以后也可以方便的改。
另外由于我们缓存可能会因为外部配置项rootStaff改变而改变,我加了一个cleanCache的方法。
cache工具类实现如下:
public class StaffCacheUtil { public static StaffCacheUtil create() { return new StaffCacheUtil(); } private Cache<String, Object> staffCache; private StaffCacheUtil() { staffCache = CacheBuilder.newBuilder() .expireAfterWrite(1, TimeUnit.DAYS) .build(); cleanCache(); } public void cleanCache() { staffCache.cleanUp(); } public Object get(String key, Callable<Object> callable) throws ExecutionException { return staffCache.get(key, callable); } public void put(String key, Object value) throws ExecutionException { staffCache.put(key, value); } }
回到业务代码,先贴一下原来的实现:
String rootStaffId = diamondVariableManager.getVariable("topUserRemoveRootStaffId"); List<StaffInfoDO> userDList = new ArrayList<StaffInfoDO>(); if(rootStaffId != null){ if(staffCache.get(activeIndex).get("rootStaffId") != null){ long now = System.currentTimeMillis(); long diff = now - time.get(); if(!rootStaffId.equals(staffCache.get(activeIndex).get("rootStaffId")) || diff > 86400*1000){ if(time.compareAndSet(now - diff, now)){ this.writeCache(rootStaffId); } } } else { this.writeCache(rootStaffId); } userDList = readCache(); } List<String> userStaffIds = new ArrayList<String>();
这里staffCache是个map,readCache和writeCache去读和写map里某个key。
而用guava的代码是:
String rootStaffFromCache = (String)staffCacheUtil.get(ROOT_STAFF, new Callable<Object>() { @Override public Object call() { staffCacheUtil.cleanCache(); return rootStaffId; } }); if (!rootStaffId.equals(rootStaffFromCache) ) { staffCacheUtil.cleanCache(); staffCacheUtil.put(ROOT_STAFF, rootStaffId); } Object obj = staffCacheUtil.get(STAFF_KEY, new Callable<Object>() { @Override public Object call() { return getStaffData(rootStaffId); } }); if (obj instanceof List && ((List)obj).get(0) instanceof StaffInfoDO) { userDList = (List<StaffInfoDO>)obj; } else { logger.error("object from cache is not List<StaffInfoDO>"); }
这里用get(KEY, Callable<>)的方法使得代码看上去更符合_如果有缓存则返回;否则运算、缓存、然后返回_的模式,也省去了writecache和readcache的实现,对我来说习惯了匿名类的话逻辑会更清晰一些。
总结
这里主要用guava缓存做了一次尝试,感觉它能很方便的让我们设置缓存策略,而它的_如果有缓存则返回;否则运算、缓存、然后返回_也让我很涨姿势。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用Live Template 增加开发效率
## 背景 最近在开发一个新项目,在写新类的时候要加log对象: private static final Logger log = LoggerFactory.getLogger(ExperienceController.class); 然后每次都忘,于是想看看有没有什么办法能简化这个流程,最后用了intellij 的live templates ## Live Template关于live template的介绍参照这里 和 这里, 它主要作用是能自定义一些代码片段的快捷方式,然后通过代码提示能快速的帮你生成代码。 它的配置地方和快捷键如下: Intellij已经集成了一些快捷项了,比如 这样你输入sy时候会提示: 按下tab键后会生成: 光标会停留在$END$处的地方方便你编辑。 除此之外,live templates还支持定义一些变量和一些内置函数,具体可以参考上面的官方文档。 另外在写新的template时候要定义使用场景,即最下方的: 点击define会弹出一个对话框: 你可以选择希望什么时候提示你的template。 实践 下面简单介绍一下我自己写的几个例子 第一个是生成...
- 下一篇
JS转PDF
前端时间调研了一下js转pdf的一些方案,做个整理。 一开始考虑前端转还是后端转,后来想想前端可能做出来和看到的会更像一点,所以先考虑前端的方案。 首先通过google和ata等搜到jsPDF这个库,不过一开始看到例子都不是把html转成pdf。 后来看了它的一些文档,里面有个fromHTML方法,不过它不支持utf8,其github上有个issue,就我看到了有这几个workaround: pdfkit pdfmake jsPDF的插件addHTML 1和2看上去比较复杂,而且也没找到明确的从HTML转pdf的方法,所以直接尝试方案三,不过有兴趣也可以研究一下。查看了addHTML的文档和代码后,写了下面这个js: var pdf = new jsPDF('p','pt','a4'); var element = $("body"); element = document.getElementsByClassName("span12")[0];//element.find('.span12'); console.log(element); pdf.addHTML(element,{ ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Hadoop3单机部署,实现最简伪集群
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8编译安装MySQL8.0.19