本文为博主原创,未经允许不得转载:

  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缓存工具类封装和使用的更多相关文章

  1. Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    Go/Python/Erlang编程语言对比分析及示例   本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...

  2. Guava 常用工具类

    引入guava包: <dependency> <groupId>com.google.guava</groupId> <artifactId>guava ...

  3. Redis操作Set工具类封装,Java Redis Set命令封装

    Redis操作Set工具类封装,Java Redis Set命令封装 >>>>>>>>>>>>>>>>& ...

  4. Redis操作List工具类封装,Java Redis List命令封装

    Redis操作List工具类封装,Java Redis List命令封装 >>>>>>>>>>>>>>>> ...

  5. Redis操作Hash工具类封装,Redis工具类封装

    Redis操作Hash工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>> ...

  6. Redis操作字符串工具类封装,Redis工具类封装

    Redis操作字符串工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>>& ...

  7. Cache【硬盘缓存工具类(包含内存缓存LruCache和磁盘缓存DiskLruCache)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 内存缓存LruCache和磁盘缓存DiskLruCache的封装类,主要用于图片缓存. 效果图 代码分析 内存缓存LruCache和 ...

  8. 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Caching; usi ...

  9. SpringBoot Redis工具类封装

    1.接口类 package com.sze.redis.util; import java.util.List; import java.util.Set; import java.util.conc ...

  10. php 缓存工具类 实现网页缓存

    php 缓存工具类 实现网页缓存 php程序在抵抗大流量访问的时候动态网站往往都是难以招架,所以要引入缓存机制,一般情况下有两种类型缓存 一.文件缓存 二.数据查询结果缓存,使用内存来实现高速缓存 本 ...

随机推荐

  1. 记一次 .NET 某药厂业务系统 CPU爆高分析

    一:背景 1. 讲故事 前段时间有位朋友找到我,说他们的程序出现了CPU爆高,让我帮忙看下怎么回事?这种问题好的办法就是抓个dump丢给我,推荐的工具就是用 procdump 自动化抓捕. 二:Win ...

  2. bash shell笔记整理——tail命令

    作用 Print the last 10 lines of each FILE to standard output. With more than one FILE, precede each wi ...

  3. 关于Secure Hash Algorithm加密算法

    一.概述 SHA(Secure Hash Algorithm)加密算法是一种广泛应用的密码散列函数,由美国国家安全局(NSA)设计,用于保障数据的安全性和完整性.SHA算法经历了多个版本的更新,目前主 ...

  4. ElasticSearch之cat count API

    读取当前存储的记录的数量. 命令样例如下: curl -X GET "https://localhost:9200/_cat/count?v=true&pretty" -- ...

  5. 中间件是开箱即用的吗?为什么要开发中间件adapter?

    本文分享自华为云社区<中间件是开箱即用的吗?为什么要开发中间件adapter?>,作者:张俭. 中间件在很多系统中都存在 在一个系统里面,或多或少地都会有中间件的存在,总会有数据库,其他的 ...

  6. SpringBoot 接口:响应时间优化9个技巧!

    今天聊聊 SpringBoot接口:响应时间优化的9个技巧.在实际开发中,提升接口响应速度是一件挺重要的事,特别是在面临大量用户请求的时候.好了,咱们直接切入正题. 本文,已收录于,我的技术网站 dd ...

  7. Spring 中循环依赖的处理

    Spring 提供了十分强大的依赖注入功能,使得我们不再需要手动去管理对象的依赖项.然而,在实际的使用场景中,可能会遇到类似下面的依赖异常: Exception encountered during ...

  8. 【开源】EDUCN网站

    EDUCN https://scrc.rth1.link/ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...

  9. 【独立闯天下】Prim新传奇!💥原团队的Blazor版本迟迟无音,合并请求石沉大海。于是,我们决定单干!加入Prime Blazor版项目,一起开创崭新的旅程吧!🌟📚

    共建Prime的Blazor版:为开源社区注入新活力 Prime组件库作为一款广受欢迎的开源组件库,一直以来都备受开发者们的青睐.然而,随着技术的不断发展和更新,原团队的Blazor版本似乎已经逐渐失 ...

  10. AI开发实践丨客流分析之未佩戴口罩识别

    摘要:通过本教程,我们可以学习客流统计应用的扩展--过线客流统计+口罩佩戴识别,可用于商超.写字楼入口安检. 本文分享自华为云社区<客流分析之未佩戴口罩识别>,作者: HiLens_fei ...