Guava缓存工具类封装和使用
本文为博主原创,未经允许不得转载:
Guava是谷歌提供的一款强大的java工具库,里面包含了很多方便且高效的工具,在项目开发中有业务场景需要保存数据到内存当中,
且只需要保存固定时间就可以,该数据只在服务调用其他服务的时候会获取。主要有两个场景:1.项目中需要调用第三方服务,第三方服务
每次调用时,需要获取第三方提供的token,,2.项目中需要校验第三方的一些固定数据。。所以考虑用Guava的缓存类,将上述中的数据
保存到Guava中,在获取的时候直接使用,如果没有则获取数据,并将其保存到Guava中。
第一步:定义Guava缓存基类,其中要实现 InitializingBean接口,这个接口为Spring提供的接口,:
import java.util.concurrent.ExecutionException; import org.apache.http.client.utils.CloneUtils;
import org.springframework.beans.factory.InitializingBean; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; /**
* 〈一句话功能简述〉<br>
* guava内存缓存基类
*
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public abstract class AbstractMemoryCache<PK, T> implements InitializingBean { private LoadingCache<PK, T> cache; protected abstract CacheBuilder<Object, Object> getCacheBuilder(CacheBuilder<Object, Object> cacheBuilder); protected abstract CacheLoader<PK, T> getCacheLoader(); protected LoadingCache<PK, T> getCache() {
return cache;
} public T getValue(PK pk) throws Exception {
try {
return CloneUtils.cloneObject(this.cache.get(pk));
} catch (CloneNotSupportedException | ExecutionException e) {
throw new Exception(e);
}
} public void setValue(PK pk, T t) {
this.cache.put(pk, t);
} @Override
public void afterPropertiesSet() throws Exception {
CacheLoader<PK, T> cacheLoader = this.getCacheLoader();
CacheBuilder<Object, Object> cacheBuilder = this.getCacheBuilder(CacheBuilder.newBuilder());
this.cache = cacheBuilder.build(cacheLoader);
} }
InitializingBean接口为spring提供的一个接口,用来加载保存数据,可打开源码看下,通过注释可了解到该接口主要用来初始化加载数据:
package org.springframework.beans.factory; /**
* Interface to be implemented by beans that need to react once all their
* properties have been set by a BeanFactory: for example, to perform custom
* initialization, or merely to check that all mandatory properties have been set.
*
* <p>An alternative to implementing InitializingBean is specifying a custom
* init-method, for example in an XML bean definition.
* For a list of all bean lifecycle methods, see the BeanFactory javadocs.
*
* @author Rod Johnson
* @see BeanNameAware
* @see BeanFactoryAware
* @see BeanFactory
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.context.ApplicationContextAware
*/
public interface InitializingBean { /**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception; }
第2步:实现基类,封装业务数据保存和调用
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import org.springframework.stereotype.Component; /**
* 〈一句话功能简述〉<br>
* 〈缓存〉
*
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
* @date 20190807
*/
@Component("tokenCache")
public class TokenCache extends AbstractMemoryCache<String, Map<String, Object>> { // 过期时间: 3小时
private static final int EXPIRE_SEC_TIME = 3; // 最多保存的key的数量
private static final int MAX_KEY_SIZE = 500;
·
·// 设置存储数量和过期时间
@Override
protected CacheBuilder<Object, Object> getCacheBuilder(CacheBuilder<Object, Object> cacheBuilder) {
return cacheBuilder.maximumSize(MAX_KEY_SIZE).expireAfterWrite(EXPIRE_SEC_TIME, TimeUnit.HOURS);
} @Override
protected CacheLoader<String, Map<String, Object>> getCacheLoader() {
return new CacheLoader<String, Map<String, Object>>() { @Override
public Map<String, Object> load(String key) throws Exception {
return new HashMap<>();
}
};
}
// 根据key获取token值
public Object genToken(String key) throws Exception { return super.getValue(key).get(key);
}
// 在guava中根据key缓存值
public void setCache(String key,Object token) {
Map<String, Object> tokenMap = new HashMap<>();
tokenMap.put(key, token);
super.setValue(key, tokenMap);
}
}
设置过期时间
在构建Cache对象时,可以通过CacheBuilder类的expireAfterAccess和expireAfterWrite两个方法为缓存中的对象指定过期时间,使用`CacheBuilder`构建的缓存不会“自动”执行清理和逐出值,也不会在值到期后立即执行或逐出任何类型。相反,它在写入操作期间执行少量维护,或者在写入很少的情况下偶尔执行读取操作。其中,expireAfterWrite方法指定对象被写入到缓存后多久过期,expireAfterAccess指定对象多久没有被访问后过期。
第三步调用:由于在第二步类上加了spring的@Component注解,在服务启动时会自动加载到服务中,当做bean正常调用即可。
具体学习可参考以下博客:
Guava Cache用法介绍
Guava缓存工具类封装和使用的更多相关文章
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
Go/Python/Erlang编程语言对比分析及示例 本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...
- Guava 常用工具类
引入guava包: <dependency> <groupId>com.google.guava</groupId> <artifactId>guava ...
- Redis操作Set工具类封装,Java Redis Set命令封装
Redis操作Set工具类封装,Java Redis Set命令封装 >>>>>>>>>>>>>>>>& ...
- Redis操作List工具类封装,Java Redis List命令封装
Redis操作List工具类封装,Java Redis List命令封装 >>>>>>>>>>>>>>>> ...
- Redis操作Hash工具类封装,Redis工具类封装
Redis操作Hash工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>> ...
- Redis操作字符串工具类封装,Redis工具类封装
Redis操作字符串工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>>& ...
- Cache【硬盘缓存工具类(包含内存缓存LruCache和磁盘缓存DiskLruCache)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 内存缓存LruCache和磁盘缓存DiskLruCache的封装类,主要用于图片缓存. 效果图 代码分析 内存缓存LruCache和 ...
- 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Caching; usi ...
- SpringBoot Redis工具类封装
1.接口类 package com.sze.redis.util; import java.util.List; import java.util.Set; import java.util.conc ...
- php 缓存工具类 实现网页缓存
php 缓存工具类 实现网页缓存 php程序在抵抗大流量访问的时候动态网站往往都是难以招架,所以要引入缓存机制,一般情况下有两种类型缓存 一.文件缓存 二.数据查询结果缓存,使用内存来实现高速缓存 本 ...
随机推荐
- 前端传递Base64字符串,后端转流存入OSS
工具类 public static BufferedInputStream base64Convert(String base64) { // 解码 base64 = base64.split(&qu ...
- MySQL运维9-Mycat分库分表之枚举分片
一.枚举分片 通过在配置文件中配置可能的枚举值,指定数据分布到不同数据节点上,这种方式就是枚举分片规则,本规则适用于按照省份,性别,状态拆分数据等业务 二.枚举分片案例 枚举分片需求:现有 tb_en ...
- Net 高级调试之十四:线程同步的基础知识和常见的同步原语
一.介绍 今天是<Net 高级调试>的第十四篇文章,这篇文章我们主要介绍和线程相关的内容,当然不是教你如何去写多线程,更不会介绍多线程的使用方法和API,今天,我们主要讲一下锁,一说到多线 ...
- 聊聊流式数据湖Paimon(三)
概述 如果表没有定义主键,则默认情况下它是仅追加 表类型(Append Only Table). 根据桶(Bucket)的定义,我们有两种不同的仅追加模式:"Append For Scala ...
- Educational Codeforces Round 159 总结
最失败的一集. C 开题顺序搞错,不小心先开了C,以为是A.还好C不难. 题意大概是在给定的数组最后添一个数(所有数两两不同),再自定义一个数 \(k\) ,数组中每个数可以加上若干个 \(k\) , ...
- ElasticSearch之cat indices API
命令样例如下: curl -X GET "https://localhost:9200/_cat/indices?v=true&pretty" --cacert $ES_H ...
- SPSC Queue
在多线程编程中,一个著名的问题是生产者-消费者问题 (Producer Consumer Problem, PC Problem). 对于这类问题,通过信号量加锁 (https://www.cnblo ...
- CSS3学习笔记-盒模型
CSS盒模型是指包含内容(content).填充(padding).边框(border)和外边距(margin)几个方面的一个矩形框模型. 内容区(content):指元素中显示内容的区域,它的大小由 ...
- 【菜鸟必看】stm32定时器的妙用
摘要:本文为你带来关于stm32定时器的使用的便利和优势之处. 使用定时器去计算获取一条的时间 一.初步了解定时器 stm32定时器时钟图如下: 定时器2-7:普通定时器定时器1.8:高级定时器 二. ...
- npm install过程中遇到typings deprecated的warning该怎么处理
摘要:在项目里进行npm install操作的时候,发现typings.json文件里的一些定义文件爆出了已经弃用的警告,怎么办? 本文分享自华为云社区<npm install过程中遇到typi ...