原文鏈接:https://clclcl.fun/2020/03/28/java/LoadingCache-null-value/
Google的guava是個很好的項目,提供了諸如集合、緩存、並發、String工具類等等,實乃Java開發利器。這里簡單說一下LoadingCache使用的一點注意事項。ifeve.com有翻譯cache相關的介紹,在這里。
使用Cache時,我們優先讀取緩存,當緩存不存在時,則從實際的數據存儲獲取,如DB、磁盤、網絡等,即get-if-absent-compute。guava提供了CacheLoader機制,允許我們通過設置Loader來自動完成這一過程。如:
Cache<String, User> cache = CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES);
user = cache.get(name, () -> {
User value = query(key);//from databse, disk, etc.
return value;
});
或者使用LoadingCache:
LoadingCache<String, User> cache = CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build(
new CacheLoader<String, User>() {
@Override
public User load(String name) throws Exception {
User value = query(key);//from databse, disk, etc.
return value;
}
}
);
這可比自己寫一個Map來緩存數據方便多了,而且還可以設置超時時間自動幫我們清理過期的數據。
不過需要注意一點的是,CacheLoader不允許返回的數據為NULL,否則會拋出異常:CacheLoader returned null for key
。所以我們需要保證查找的數據必須存在,或者拋出異常外部處理。在某些情況下,我們的數據可能確實不在,比如用戶管理模塊,我們在新增數據前,要查詢原來是否已經存在該用戶,那么這時候拋出異常也不合適,此時可以使用Optional來優化CacheLoader:
LoadingCache<String, Optional<User>> cache = CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build(
new CacheLoader<String, Optional<User>>() {
@Override
public Optional<User> load(String name) throws Exception {
User value = query(key);//from databse, disk, etc.
return Optional.ofNullable(value);
}
}
);
這樣我們保證了CacheLoader返回值不為NULL,而業務數據是否存在,只需要判斷Optional.ifPresent()就行了,同時Optional的其他函數在業務邏輯中也是非常有用的。