最常见用法
private final Cache<String, Boolean> executedTaskTypes = Caffeine.newBuilder().expireAfterWrite(120, TimeUnit.SECONDS).build();
查询不到时,自动查询数据源
import com.github.benmanes.caffeine.cache.*;
import java.util.concurrent.TimeUnit;
import java.util.*;
public class CaffeineCacheExample {
public static void main(String[] args) {
// 创建一个 Caffeine 缓存
LoadingCache<String, String> cache = Caffeine.newBuilder()
.expireAfterWrite(120, TimeUnit.SECONDS) // 键在写入后120秒过期
.refreshAfterWrite(100, TimeUnit.SECONDS) // 键写入100秒后进行刷新
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 当缓存中找不到数据时,从外部数据源加载数据
return loadFromDatabase(key);
}
@Override
public Map<String, String> loadAll(Set<? extends String> keys) throws Exception {
// 批量加载多个键的值
return loadAllFromDatabase(keys);
}
});
// 使用缓存
String value = cache.get("key1"); // 如果缓存中没有,会调用 load 方法
System.out.println("Value for key1: " + value);
}
// 模拟从数据库中加载单个键的值
private static String loadFromDatabase(String key) {
System.out.println("Loading from database for key: " + key);
// 这里可以实现实际的数据库查询逻辑
return "Value for " + key;
}
// 模拟从数据库中批量加载多个键的值
private static Map<String, String> loadAllFromDatabase(Set<? extends String> keys) {
System.out.println("Loading from database for keys: " + keys);
// 这里可以实现实际的数据库查询逻辑
Map<String, String> result = new HashMap<>();
for (String key : keys) {
result.put(key, "Value for " + key);
}
return result;
}
}
批量定时刷新的机制
refreshAfterWrite 的行为并不是在后台定时自动更新缓存中的数据,而是在数据被访问时触发刷新操作。也就是说,只有在缓存中的数据被请求时,且数据已经超过了刷新时间间隔,才会进行刷新操作。
//创建自更新缓存,实现在快要失效时,批量更新
pointPoint = Caffeine.newBuilder()
.expireAfterWrite(120, TimeUnit.SECONDS) //键在写入后120秒过期
.refreshAfterWrite(100, TimeUnit.SECONDS) //键写入5秒后进行刷新,一直自动更新,而是会在下次访问该键时触发更新操作。
.scheduler(Scheduler.systemScheduler()) //使用系统调度器来处理刷新任务。
.build(new CacheLoader<String,Long>() {
@Override
public Long load(String s) throws Exception {
return null;
}
@Override
public Map<? extends String, ? extends Long> loadAll(Set<? extends String> keys) throws Exception { //批量查询时,或者批量refreshAfterWrite刷新时,会调用此方法进行刷新。实际上只有在getAll时才会触发loadAll方法
return CacheLoader.super.loadAll(keys);
}
});