Guava Cache 学习使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zc_ad/article/details/84989278

Guava是什么?

Guava是一组Java的Google核心库,包括新的集合类型(例如multimap和multiset),不可变集合,图形库,函数类型,内存缓存以及用于并发,I / O,散列,基元的API /实用程序,反射,字符串处理等等!

Guava Cache呢?

当然是Guava的核心库之一,主要是用在数据的缓存。它有两种实现方式:CacheLoaderCallable

其他介绍我就不多说了,网上搜了一下,基本上都是此项目在GitHub上的翻译,github地址:https://github.com/google/guava/wiki/CachesExplained

1.引用

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>19.0</version>
</dependency>

2.CacheLoader实现缓存

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.concurrent.TimeUnit;

/**
 * Created by XiChuan on 2018-12-11.
 */
public class TestGoogleCache {

    //创建Cache
    static LoadingCache<String, Object> cache =
            CacheBuilder.newBuilder()
                    .refreshAfterWrite(4, TimeUnit.SECONDS) //设置缓存获取时长,如果key过期,就会在缓存中删除此value
                    .maximumSize(10)                                 //最大缓存数量
                    .build(new CacheLoader<String, Object>() {
                        @Override
                        /** 当本地缓存没有此key的value值时,就会调用load方法进行查询,并添加到缓存中 **/
                        public Object load(String appKey) {
                            return queryFromDB(appKey);
                        }

                    });

    /** 数据进行库进行查询**/
    public static Object queryFromDB(String appKey){
        System.out.println("query from db");
        return System.currentTimeMillis();
    }

    public static void main(String[] args)throws Exception{

        String key = "wechat";
        for (int i=0; i<8; i++){
            System.out.println("-----------i="+i+"------------------");
            System.out.println("从cache获取的值为:"+cache.get(key));
            Thread.sleep(1000);   /**每获取一次睡眠1秒*/
        }
    }
}

日志:

-----------i=0------------------
query from db
从cache获取的值为:1544687107838
-----------i=1------------------
从cache获取的值为:1544687107838
-----------i=2------------------
从cache获取的值为:1544687107838
-----------i=3------------------
从cache获取的值为:1544687107838
-----------i=4------------------
从cache获取的值为:1544687107838
-----------i=5------------------
query from db
从cache获取的值为:1544687112842
-----------i=6------------------
从cache获取的值为:1544687112842
-----------i=7------------------
从cache获取的值为:1544687112842

Process finished with exit code 0

我们看日志可以看出,当第一次再cache中获取值的时候,key=wechat并没有value值,Cache会从数据库中查询。到第五秒的时候,key=wechat到期,Cache会删除value,并从数据库中重新获取。

3.Callable实现缓存


/**
 * Created by XiChuan on 2018-12-11.
 */
public class TestGoogleCache {

    //创建Cache
    static Cache<String,Object> cache =
            CacheBuilder.newBuilder()
                    .maximumSize(10)    //设置最大缓存数量
                    .expireAfterWrite(4,TimeUnit.SECONDS)  //设置缓存过期时间
                    .build();

    /**从缓存中获取值*/
    public static Object getValueFromCache(String appKey)throws Exception{
        return cache.get(appKey, new Callable<Object>() {
            /**当本地缓存没有此key的value值时,就会调用load方法进行查询,并添加到缓存中 */
            @Override
            public Object call() throws Exception {
                return queryFromDB(appKey);
            }
        });
    }

    /** 数据进行库进行查询**/
    public static Object queryFromDB(String appKey){
        System.out.println("query from db");
        return System.currentTimeMillis();
    }

    public static void main(String[] args)throws Exception{
        String key = "wechat";
        for (int i=0; i<8; i++){
            System.out.println("-----------i="+i+"------------------");
            System.out.println("从cache获取的值为:"+getValueFromCache(key));
            Thread.sleep(1000);   /**每获取一次睡眠1秒*/
        }
    }
}

日志:

-----------i=0------------------
query from db
从cache获取的值为:1544687715137
-----------i=1------------------
从cache获取的值为:1544687715137
-----------i=2------------------
从cache获取的值为:1544687715137
-----------i=3------------------
从cache获取的值为:1544687715137
-----------i=4------------------
query from db
从cache获取的值为:1544687719149
-----------i=5------------------
从cache获取的值为:1544687719149
-----------i=6------------------
从cache获取的值为:1544687719149
-----------i=7------------------
从cache获取的值为:1544687719149

Process finished with exit code 0

可以看出,处理的结果都是一样的。

4.其他有用的方法

有时候,我们并不想当缓存时间过期后才清除缓存项,我们可以显式地将缓存清除。 
Cache.invalidate(key)             //清除一个缓存 
Cache.invalidateAll(keys)       //根据keys批量清除
Cache.invalidateAll()              //清除所有缓存

5.对Callable实现方式进行封装

@Configuration
public class CacheConfig {

    public final static long CACHE_MAX_SIZE = 20;   //最大缓存数量

    public final static int CACHE_REFRESH = 10;     //失效时长

    @Bean(name = "access_token")
    public Cache<String,Object> accessTokenCache(){
        return CacheBuilder.newBuilder()
                .maximumSize(CACHE_MAX_SIZE)
                .expireAfterWrite(CACHE_REFRESH, TimeUnit.SECONDS)
                .build();
    }
    public static Object getValue(Cache<String,Object> cache, String key, Callable<Object> callable)throws ExecutionException{
        return cache.get(key,callable);
    }

}
public interface WechatService {
    Object getAccessToken()throws Exception;
}
/**
 * Created by XiChuan on 2018-12-13.
 */
@Service
public class WechatServiceImpl implements WechatService {
    
    @Autowired
    @Qualifier(value = "access_token")
    Cache<String,Object> accessTokenCache;

    /** 从缓存中获取accessToken */
    @Override
    public Object getAccessToken() throws Exception{
        return CacheConfig.getValue(accessTokenCache,"XICHUAN",() -> getFromApi());
    }
    
    /**模拟通过接口获取accessToken*/
    private String getFromApi(){
        System.out.println("-----从数据库中读取------------");
        return "1234567890zxcvbnm";
    }
}

此封装方式是在公司中看到大神封装的,看完后感觉挺实用的,然后就借鉴过来自己封装了一下。

猜你喜欢

转载自blog.csdn.net/zc_ad/article/details/84989278