使用GuavaCache的一些姿势

        最近写一个小项目,遇到一个高频查询功能,使用redis又有点浪费,就决定采用本地缓存来实现,于是就想到了一直很火的GuavaCache,这里对使用GuavaCache做一些小结。

        (在查资料的过程中,发现springBoot 2.x版本中已经移除了GuavaCache的支持,改用了Caffeine,这个需要抽空看看了)

        整合起来很简单,具体如下:

LoadingCache<String, Integer> LOGIN_CACHE = CacheBuilder.newBuilder()
            .maximumSize(100) // 设置缓存的最大容量
            .expireAfterWrite(5, TimeUnit.SECONDS) // 测试用,5秒后失效
            .concurrencyLevel(10) // 设置并发级别为10
            .recordStats() // 开启缓存统计,生产不建议使用
            .removalListener(notification -> log.info(notification.getKey() + " " + notification.getValue() + " 被移除,原因:" + notification.getCause()))
            .build(new UserInfoLoad());

public class UserInfoLoad extends CacheLoader<String, Integer> {
        @Override
        public Integer load(String key) {
            UserInfoExample userInfoExample = new UserInfoExample();
            userInfoExample.createCriteria().andUuidEqualTo(key);
            List<UserInfo> userInfos = userInfoMapper.selectByExample(userInfoExample);
            if (CollectionUtils.isEmpty(userInfos)) {
                return 0;
            }
            return userInfos.get(0).getId();
        }
    }

        可以看到代码中我增加了removalListener,是为了验证一个问题:guavaCache只有在被触发时才会进行过期缓存清理,极端情况下,如果缓存很多以后,不再有方法触发它,那就会造成内存泄露了。不过这个极端情况几乎不会发生,设计的时候注意一下即可。

        这里还遇到了第一个比较蠢得问题,我一开始将这个方法写在了service的方法内,结果每次调用都会查库,没有实现缓存的效果,反应了好一阵才想起来应该把这段代码移出方法体,哎。

        然后我又想把这段逻辑做成一个静态方法类,这样所有需要获取用户信息的方法都可以调用。这样做本身是没任何问题的,但是执行的时候,会报userInfoMapper空指针异常,查询相关资料才发现原来spring不会注入静态属性。静态属性需要手动注入set方法。

private static UserInfoMapper userInfoMapper;

    @Autowired
    public void setUserInfoMapper(UserInfoMapper userInfoMapper) {
        UserCache.userInfoMapper= userInfoMapper;
    }

        这样一个简单的GuavaCache实现就做好了。小型项目,或者配置不高的情况下,确实没必要安装那么多中间件,可以本地实现的话最好不过了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章