Google Guava Cache 简单使用示例

1,248 阅读2分钟

我们在使用JDK的本地缓存时,通常使用HashMap或者ConcurrentHashMap来做本地缓存。比如在只读数据(加载字典表数据),或者每个部署节点独立的数据时(长连接服务中,每个部署节点由于都是维护了不同的连接,每个连接的数据都是独立的)。
在以前加载字典表的时候,处理方式可能就是在系统启动的时候,把字典表或者配置表的信息一次全部加载到 HashMap,需要自己处理数据过期或者有效性问题。如果在 HashMap中没有,从数据库查出数据,数据库有数据在手动把数据放到HashMap中的过程都需要程序员自己处理。
使用Guava Cache,上述的从数据库查出数据,数据库有数据在手动把数据放到HashMap中的过程就不需要我们手动处理,我们只需要定义好从数据库取数据的逻辑即可。
下面是一个简单的使用示例,用properties代替数据库做数据源:

public class GuavaCache {

    private PropertiesUtil putil = new PropertiesUtil();

    LoadingCache<String, String> cache = null;

    private void init() {
        cache = CacheBuilder.newBuilder()
                //cache最大容量
                .maximumSize(2)
                //缓存项在给定时间内没有被写访问(创建或覆盖),则回收。如果认为缓存数据总是在固定时候后变得陈旧不可用,这种回收方式是可取的。
                .expireAfterWrite(1, TimeUnit.MINUTES)
                //声明一个监听器,以便缓存项被移除时做一些额外操作
                .removalListener(new MyListener())
                .build(new CacheLoader<String, String>() {
                    @Override
                    public String load(String key) throws Exception {
                        return putil.get(key);
                    }
                });
    }

    public static void main(String[] args) throws Exception {
        GuavaCache cache = new GuavaCache();
        cache.init();
        cache.testCache();
    }

    private void testCache() {
        try {
            System.out.println("before:" + cache.size());
            String name = cache.get("app.name");
            cache.get("app.version");
            cache.get("app.port");
            System.out.println("after:" + cache.size());
            System.out.println("name :" + name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private class MyListener implements RemovalListener<String, String> {
        @Override
        public void onRemoval(RemovalNotification<String, String> removalNotification) {
            String key = removalNotification.getKey();
            String value = removalNotification.getValue();
            RemovalCause cause = removalNotification.getCause();
            System.out.println("key:"+ key + ",value:" + value + " removed, cause:" + cause.toString());
        }
    }
}

执行结果如下:

before:0
key:app.name,value:MyApp removed, cause:SIZE
after:2
name :MyApp

在guava cache中,每次get的时候,缓存中如果没有,就通过我们实现的CacheLoader类中的load方法来加载数据到缓存中。
因为我们定义的cache最大容量为2(maximumSize),第三次get的时候,超过了最大的数据容量,移除数据时会回调 RemovalListener。