2015-06-03 3 views
2

Использование абстракции кэширования Spring, как я могу кэшировать обновление асинхронно, сохраняя при этом старую запись?Обновление асинхронного кэша с абстракцией весеннего кэша

Я пытаюсь использовать абстракцию кэширования Spring, чтобы создать систему кэширования, где после относительно короткого «мягкого» тайм-аута записи кэша становятся доступными для обновления. Затем, когда они запрашиваются, возвращается кешированное значение и запускается операция асинхронного обновления для обновления записи. Я бы также

Builder-хранилище Guava позволяет мне указать, что записи в кеше должны быть обновлены через определенное время. Метод reload() загрузчика кэша затем может быть переопределен асинхронной реализацией, позволяя вернуть устаревшее кэшированное значение до тех пор, пока не будет получен новый. Тем не менее, весеннее кэширование, похоже, не использует CacheLoader для лежащего в основе кэша Guava.

Возможно ли это обновление асинхронного кеша, используя абстракцию кэширования Spring?

Редактировать, чтобы уточнить: С помощью CacheBuilder от Guava я могу использовать 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; 
      } 
     } 
     }); 

Однако, я не могу видеть способ получить поведение refreshAfterWrite() с помощью @Cacheable абстракции Spring в.

+0

как об этом. https://github.com/kimwz/caffeine-cache-annotation –

ответ

2

Может быть, вы могли бы попробовать что-то вроде:

  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() invoke ту же функцию, чтобы вернуть значение, которое нужно кэшировать. controller ссылаются только getStringCache().

  3. Обновить кэш с запланированными задачами doc

    @Configuration 
    @EnableScheduling 
    public class ScheduledTasks { 
    
        @Autowired 
        private MyService myService; 
    
        @Scheduled(fixedDelay = 30000) 
        public void IaaSStatusRefresh(){ 
         myService.refreshStringCache(); 
        } 
    } 
    

    Таким образом, запланированное задание вынуждает кэш обновляется каждые 30 секунд. Любой, кто обратился к getStringCache(), найдет обновленные данные в кеш.

+0

Правильно ли я понимаю? Кажется, что это обновит каждую запись в кеше каждые 30 секунд, что на самом деле не так, как я хочу. После того, как объект находился в кеше в течение 30 секунд, я хочу, чтобы он получил право на обновление. Тогда в следующий раз, когда этот объект будет извлечен из кеша, я хочу, чтобы он вызывал асинхронное обновление. –

+0

Извините, вы правильно поняли. Я не знаю, поддерживает ли Spring эти функции – Matteo

0

В одном проекте с использованием Spring Cache абстракции, я сделал следующие вещи, чтобы достичь те же целей, но все-таки удается скрыть фактическое VENDER кэша, то есть, он должен работать с пружинными опорами независимо от поставщика кэша (в настоящее время гуавы , но при необходимости приложение может переключиться на поставщика кластерного кеша).

Основная концепция заключается в «захвате» шаблонов использования кеша и «повторении» этих операций в других потоках фона, возможно, с помощью планировщика.

Необходимо использовать отражение и некоторое программирование АОП для части «захвата», если я хочу, чтобы код был неинтрузивным, и, к счастью, Spring, Spring AOP предоставляет все необходимые мне инструменты.

Смежные вопросы