我有一个调用外部系统的服务,通过它们的外部id来检索某种对象,并将它们提交回更新。而不是一个接一个地检索对象,有一个更通用的目的方法:
public interface ExternalSystem {
List<ExternalDTO> getObjects(List<String> externalIds);
void updateObjects(List<ExternalDTO> updates);
}
我想在ExternalSystem调用上放置一个缓存,因为它们的开销相当大。
在服务的实现中,我可以简单地放置spring注解:
@Cacheable("cache-external")
List<ExternalDTO> getObjects(List<String> externalIds) {}
@CacheEvict(cacheNames="cache-external", allEntries=true)
void updateObjects(List<ExternalDTO> updates);
然而,如果externalId之间有很多交集,这样的缓存将表现得非常糟糕,即
1.调用#1 getObjects([1,2,3,4])-〉通过[1,2,3,4]键放置缓存
1.调用#2 getObjects([1,2,3,4,5])-〉通过[1,2,3,4,5]键放置缓存
1.调用#3 getObjects([6,7,8,9])-〉通过[6,7,8,9]键放置缓存
1.调用#4 updateObjects(1)-〉清除所有缓存,但第三个缓存不包含3
因此,问题是如何实现定制策略(我假设它是不可实现的开箱即用),该策略将只驱逐那些真正应该被驱逐的条目,并将使键以这样的方式该高速缓存中检索相交对象?
**更新。**我发现了两个类似的问题:
- spring-cache-abstraction-with-multi-value-queries
- using-spring-cache-on-methods-that-take-an-array-or-collection
- spring-cacheable-methods-with-lists
**Upd 2.**下面的代码与我想要的代码类似,不同之处在于我将为集合中的每个项放入String和ExternalDTO对的缓存中。element-level-caching-of-list-to-list
2条答案
按热度按时间mpgws1up1#
AFAIK注解是不可能的,你可以使用命令式API,它包含你需要的批量操作,例如
Cache.getAll(keySet)
和Cache.removeAll(keySet)
wztqucjr2#
对我来说,它在这个配置下工作得很好。这是我的代码的模糊版本。
你可以看到它连接了字符串
我的设置:/资源/ehcache.xml
gradle.build