在采用数组或集合参数的方法上使用Spring Cache有哪些策略?

时间:2015-11-11 18:59:48

标签: spring caching spring-cache

我想使用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缓存这种方法有哪些策略?

2 个答案:

答案 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)将处理缓存密钥和相应值的集合。

这种方法的局限性很少:

  1. 缓存未命中全部或全部;即,如果缺少任何单个密钥,则缓存的部分密钥将被视为未命中。 Spring(OOTB)不允许您同时返回缓存值并调用diff的方法。这需要对Cache Abstraction进行一些非常广泛的修改,我不建议这样做。

  2. 我的实现只是一个示例,所以我选择不实施Cache.putIfAbsent(key, value)操作(here)。

  3. 虽然我的实施工作正常,但可以使其更加健壮。

  4. 无论如何,我希望它提供了一些如何正确处理这种情况的见解。

    测试类是自包含的(使用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以及其他类型的软件。