java - 使用 Spring 缓存抽象的异步缓存更新

标签 java spring caching asynchronous spring-cache

使用 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() 行为的方法。

最佳答案

也许你可以尝试这样的事情:

  1. 配置缓存:

    @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;
        }
    }
    
  2. 读取要缓存的值假设是一个字符串(我用一个@Service作为例子)

    @Service
    public class MyService{
    
        @Cacheable("cacheKey")
        public String getStringCache() {
            return doSomething();
        }
    
        @CachePut("cacheKey")
        public String refreshStringCache() {
            return doSomething();
        }
        ...
    }
    

    getStringCache()refreshStringCache() 调用相同的函数以检索要缓存的值。 Controller 调用 getStringCache()

  3. 使用计划任务刷新缓存 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/

相关文章:

JavaFX 标签换行文本行距

jquery - 错误解析模板,当我什至没有要求一个时

c++ - 缓存链表——这可能吗?

python - Flask 和长时间运行的任务

javascript - Leaflet 标记弹出窗口中的缓存破坏

java - ClassNotFoundException com.sun.mail.util.SharedByteArrayInputStream

Windows下Java Classloader不释放文件句柄

java - 使用 Java 在 OS X 中获取文件扩展名

java - 更改 NoSuchBeanDefinitionException 上的 Spring 行为

json - Jackson 将 ""反序列化为空列表