我想使用Spring的Cache抽象来将方法注释为@Cacheable。但是,某些方法旨在获取数组或参数集合并返回集合。例如,考虑这种方法来寻找诱惑:
public Collection<Entity> getEntities(Collection<Long> ids)
从语义上讲,我需要单独缓存Entity
个对象(由id键入),而不是基于整个ID集合。与Simple Spring Memcached提出的问题类似。
ReadThroughMultiCache
通过其{{3}}支持我想要的东西,但我想使用Spring的抽象来支持轻松更改缓存存储实现(Guava,Coherence,Hazelcast,等),而不仅仅是memcached。
使用Spring Cache缓存这种方法有哪些策略?
答案 0 :(得分:5)
Spring's Cache Abstraction不支持这种开箱即用的行为。但是,这并不意味着它是不可能的;支持期望的行为只需要更多的工作。
我写了一篇小example来展示开发人员如何实现这一目标。该示例使用Spring的ConcurrentMapCacheManager来演示自定义。此示例需要适应您所需的缓存提供程序(例如Hazelcast,Coherence等)。
简而言之,您需要覆盖CacheManager实现的“装饰”Cache的方法。这从实施到实施各不相同。在ConcurrentMapCacheManager
中,方法为createConcurrentMapCache(name:String)。在Spring Data GemFire中,您将覆盖getCache(name:String)方法来修饰返回的Cache。对于番石榴,它将是GuavaCacheManager
中的createGuavaCache(name:String),依此类推。
然后你的custom, decorated Cache implementation(可能/理想情况下,从Cache impl委托给实际this)将处理缓存密钥和相应值的集合。
这种方法的局限性很少:
缓存未命中全部或全部;即,如果缺少任何单个密钥,则缓存的部分密钥将被视为未命中。 Spring(OOTB)不允许您同时返回缓存值并调用diff的方法。这需要对Cache Abstraction进行一些非常广泛的修改,我不建议这样做。
我的实现只是一个示例,所以我选择不实施Cache.putIfAbsent(key, value)操作(here)。
虽然我的实施工作正常,但可以使其更加健壮。
无论如何,我希望它提供了一些如何正确处理这种情况的见解。
测试类是自包含的(使用Spring JavaConfig),并且可以在没有任何额外依赖性的情况下运行(超出Spring,JUnit和JRE)。
干杯!
答案 1 :(得分:0)
为我工作。这是我的答案的链接。 https://stackoverflow.com/a/60992530/2891027
TL:DR
@Cacheable(cacheNames = "test", key = "#p0")
public List<String> getTestFunction(List<String> someIds) {
我的示例是使用String的,但也可以使用Integer和Long以及其他类型的软件。