使用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實現就做好了。小型項目,或者配置不高的情況下,確實沒必要安裝那麼多中間件,可以本地實現的話最好不過了。

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