2017-04-21 108 views
1

我需要对弹簧缓存功能有一些基本的了解。我想构建一个缓存加热器和resyncer作为计划bean,以便在发生更改时按需更新缓存。春季开机缓存热身

比方说,我有一个AccountClientgetAccount(String id),它从一个非常缓慢的API中获取Account。所以基本上我可以做

@Cachable(cacheNames = "account", key = "#id", sync = true) 
public Account getAccount(String id) { 
    //... 
} 

和一切工作正常。现在我想预热缓存,而且,我得到了一个getNewOrChangedAccounts(),它从缓慢的数据存储中检索已更改帐户的ID。

所以这里是我的方法:

public class AccountCacheManager { 

    //... 

    @Scheduled(initialDelay = 3000L, fixedRate = 10000L) 
    public void sync() { 
     List<Account> modifiedAccounts = accountClient.getNewOrChangedAccounts(); 

     modifiedAccounts.getAccounts().parallelStream() 
       .forEach(account -> { 
        //delete old entry 
        evictAccount(account.getId()); 
        //store new entry 
        putAccount(account.getId()); 

       }); 


     log.info("finished resync"); 
    } 

    @CacheEvict(cacheNames = "account", key = "#id") 
    public void evictAccount(String id) { 
     log.debug("evicting account {}", id); 
    } 

    @CachePut(cacheNames = "account", key = "#id") 
    public void putAccount(String id) { 
     log.debug("storing account {}", id); 
     accountService.getAccount(id); 
    } 
} 

,所以我可以证明,这个过程被启动,并且做一些事情。但是,当我点击我的API时,即使我的同步检查了后端的所有条目,我也会看到第一次打到后端缓慢。

我觉得我误解了Spring缓存API的一些细节,所以我怎么能做到这一点?

回答

1

documentation@CachePut

与此相反的@Cacheable注释,此注释不 导致跳过的建议方法。相反,它始终会导致调用 方法,并将其结果存储在关联的 缓存中。

所以你用@CachePut标注的方法应该将数据返回到高速缓存:

@CachePut(cacheNames = "account", key = "#id") 
    public Account putAccount(String id) { 
     log.debug("storing account {}", id); 
     return accountService.getAccount(id); 
    } 

另见这个问题:Spring Cacheable vs CachePut?

+0

THX!我忘了返回值! –

+0

几天后,它仍然无法正常工作......正在缓存工作中分离请求? –

+0

它看起来像直接使用'CacheManager'时工作,只需使用@CachePut注释并返回是不够的 –