是否可以配置Spring @Cacheable
,以便在缓存未命中时,对可缓存方法的调用将被阻塞,直到可缓存方法执行一次并填充缓存为止?
在我的情况下,我正在处理来自db的数据,如果此数据发生更改,则实际上不会经常更改,然后需要重新启动应用程序。我可以创建@PostConstruct
方法并在每个服务启动时初始化数据,但这似乎不像@Cacheable
注释那样“优雅”。
我计划将EhCache与Spring @Cacheable
注释一起使用。
更新
以下是我在尝试使用@PostConstruct时遇到的一些问题,以防其他人遇到这些问题。 @PostConstruct
方法不能是@Transactional
,因为它们在设置对象的属性后运行,而不是在配置完整的spring上下文之后运行。所以你不能假设TX管理器是在调用时@PostConstruct
方法的时候全部设置和配置的。解决方法是实现ApplicationListener
并手动注入TransactionTemplate ...等使用@Cacheable
简化了许多额外的工作。
答案 0 :(得分:2)
Spring 4.3中添加了对同步缓存的支持:
@Service
public class FooService {
@Cacheable(cacheNames = "foos", sync = true)
public Foo getFoo(String id) { ... }
}
请参阅:https://spring.io/blog/2016/03/04/core-container-refinements-in-spring-framework-4-3
答案 1 :(得分:1)
我不认为@PostConstruct
不优雅,对我来说似乎是完美的解决方案。您希望仅在重新启动应用程序时调用方法。还有什么比这更好的?
但是你也可以这样做来阻止调用,直到缓存可用
@Cacheable(cacheName="yourCache", decoratedCacheType= DecoratedCacheType.SELF_POPULATING_CACHE)
public List<String> getWhatever(int id) {
//call database
}
并使缓存自动刷新:
@Cacheable(cacheName="yourCache", refreshInterval=1000, decoratedCacheType= DecoratedCacheType.REFRESHING_SELF_POPULATING_CACHE)
public List<String> getWhatever(int id) {
//call database
}
答案 2 :(得分:1)
“阻止并发未命中”直接由(令人讨厌的注释名称)@Cacheable
from ehcache-spring-annotations支持。只需设置selfPopulating = true
。
Spring XML配置比使用Spring @Cacheable
更清晰。
最大的缺点是你将被绑定到ehcache并且无法连接其他实现(例如,对单元测试很有用)。