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程序在抵抗大流量访问的时候动态网站往往都是难以招架,所以要引入缓存机制,一般情况下有两种类型缓存 一.文件缓存 二.数据查询结果缓存,使用内存来实现高速缓存 本 ...
随机推荐
- 记一次 .NET 某药厂业务系统 CPU爆高分析
一:背景 1. 讲故事 前段时间有位朋友找到我,说他们的程序出现了CPU爆高,让我帮忙看下怎么回事?这种问题好的办法就是抓个dump丢给我,推荐的工具就是用 procdump 自动化抓捕. 二:Win ...
- bash shell笔记整理——tail命令
作用 Print the last 10 lines of each FILE to standard output. With more than one FILE, precede each wi ...
- 关于Secure Hash Algorithm加密算法
一.概述 SHA(Secure Hash Algorithm)加密算法是一种广泛应用的密码散列函数,由美国国家安全局(NSA)设计,用于保障数据的安全性和完整性.SHA算法经历了多个版本的更新,目前主 ...
- ElasticSearch之cat count API
读取当前存储的记录的数量. 命令样例如下: curl -X GET "https://localhost:9200/_cat/count?v=true&pretty" -- ...
- 中间件是开箱即用的吗?为什么要开发中间件adapter?
本文分享自华为云社区<中间件是开箱即用的吗?为什么要开发中间件adapter?>,作者:张俭. 中间件在很多系统中都存在 在一个系统里面,或多或少地都会有中间件的存在,总会有数据库,其他的 ...
- SpringBoot 接口:响应时间优化9个技巧!
今天聊聊 SpringBoot接口:响应时间优化的9个技巧.在实际开发中,提升接口响应速度是一件挺重要的事,特别是在面临大量用户请求的时候.好了,咱们直接切入正题. 本文,已收录于,我的技术网站 dd ...
- Spring 中循环依赖的处理
Spring 提供了十分强大的依赖注入功能,使得我们不再需要手动去管理对象的依赖项.然而,在实际的使用场景中,可能会遇到类似下面的依赖异常: Exception encountered during ...
- 【开源】EDUCN网站
EDUCN https://scrc.rth1.link/ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...
- 【独立闯天下】Prim新传奇!💥原团队的Blazor版本迟迟无音,合并请求石沉大海。于是,我们决定单干!加入Prime Blazor版项目,一起开创崭新的旅程吧!🌟📚
共建Prime的Blazor版:为开源社区注入新活力 Prime组件库作为一款广受欢迎的开源组件库,一直以来都备受开发者们的青睐.然而,随着技术的不断发展和更新,原团队的Blazor版本似乎已经逐渐失 ...
- AI开发实践丨客流分析之未佩戴口罩识别
摘要:通过本教程,我们可以学习客流统计应用的扩展--过线客流统计+口罩佩戴识别,可用于商超.写字楼入口安检. 本文分享自华为云社区<客流分析之未佩戴口罩识别>,作者: HiLens_fei ...