使用 Spring 的缓存抽象,如何让缓存异步刷新条目,同时仍返回旧条目?
我正在尝试使用 Spring 的缓存抽象来创建一个缓存系统,在该系统中,在相对较短的“软”超时后,缓存条目有资格进行刷新。然后,当它们被查询时,返回缓存的值,并启动异步更新操作来刷新条目。我也会
Guava 的缓存构建器允许我指定缓存中的条目应在一定时间后刷新。然后可以使用异步实现覆盖缓存加载器的 reload() 方法,允许返回陈旧的缓存值,直到检索到新值。但是,spring caching好像没有使用底层Guava缓存的CacheLoader
是否可以使用 Spring 的缓存抽象来执行这种异步缓存刷新?
编辑澄清: 使用 Guava 的 CacheBuilder,我可以使用 refreshAfterWrite() 来获得我想要的行为。例如来自 Guava Caches Explained :
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return getGraphFromDatabase(key);
}
public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
if (neverNeedsRefresh(key)) {
return Futures.immediateFuture(prevGraph);
} else {
// asynchronous!
ListenableFutureTask<Graph> task = ListenableFutureTask.create(new Callable<Graph>() {
public Graph call() {
return getGraphFromDatabase(key);
}
});
executor.execute(task);
return task;
}
}
});
但是,我看不到使用 Spring 的 @Cacheable 抽象来获取 refreshAfterWrite() 行为的方法。
最佳答案
也许你可以尝试这样的事情:
配置缓存:
@Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { SimpleCacheManager simpleCacheManager = new SimpleCacheManager(); GuavaCache chache= new GuavaCache("cacheKey", CacheBuilder.newBuilder().build()); simpleCacheManager.setCaches(Arrays.asList(cacheKey)); return simpleCacheManager; } }
读取要缓存的值假设是一个字符串(我用一个
@Service
作为例子)@Service public class MyService{ @Cacheable("cacheKey") public String getStringCache() { return doSomething(); } @CachePut("cacheKey") public String refreshStringCache() { return doSomething(); } ... }
getStringCache()
和refreshStringCache()
调用相同的函数以检索要缓存的值。Controller
调用仅getStringCache()
。使用计划任务刷新缓存 doc
@Configuration @EnableScheduling public class ScheduledTasks { @Autowired private MyService myService; @Scheduled(fixedDelay = 30000) public void IaaSStatusRefresh(){ myService.refreshStringCache(); } }
通过这种方式,计划任务会强制缓存每 30 秒刷新一次。 访问
getStringCache()
的任何人都会在缓存中找到更新的数据。
关于java - 使用 Spring 缓存抽象的异步缓存更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30615527/