10

Spring のキャッシングの抽象化を使用して、古いエントリを返しながらキャッシュに非同期的にエントリを更新させるにはどうすればよいですか?

Spring のキャッシング抽象化を使用して、比較的短い「ソフト」タイムアウトの後、キャッシュ エントリがリフレッシュの対象となるキャッシング システムを作成しようとしています。その後、クエリが実行されると、キャッシュされた値が返され、非同期更新操作が開始されてエントリが更新されます。私も

Guava のキャッシュ ビルダーを使用すると、一定時間後にキャッシュ内のエントリを更新するように指定できます。その後、キャッシュローダーの reload() メソッドを非同期実装でオーバーライドして、新しい値が取得されるまで古いキャッシュ値を返すことができます。ただし、春のキャッシュは、基になる 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() の動作を取得する方法がわかりません。

4

2 に答える 2

6

おそらく、次のようなことを試すことができます。

  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例として a を使用します)

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

    キャッシュされる値を取得するために、 と の両方で同じ関数getStringCache()を呼び出します。呼び出しのみrefreshStringCache()_controller getStringCache()

  3. スケジュールされたタスクドキュメントでキャッシュを更新する

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

    このように、スケジュールされたタスクは 30 秒ごとに強制的にキャッシュを更新します。にアクセスした人は誰でもgetStringCache()、更新されたデータをキャッシュに見つけます。

于 2015-06-25T10:39:52.610 に答える