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

E-R*_*Riz 6 spring caching spring-cache

我想使用Spring的Cache抽象将方法注释为@Cacheable。但是,某些方法被设计为采用参数的数组或集合并返回一个集合。例如,考虑使用以下方法查找实体:

public Collection<Entity> getEntities(Collection<Long> ids)
Run Code Online (Sandbox Code Playgroud)

从语义上讲,我需要Entity单独缓存对象(由id键),而不是基于整个ID的集合。类似于这个问题在问什么。

简单的Spring Memcached通过其支持了我想要的ReadThroughMultiCache,但是我想使用Spring的抽象来支持轻松更改缓存存储实现(Guava,Coherence,Hazelcast等),而不仅仅是memcached。

有哪些策略可以使用Spring Cache缓存这种方法?

Joh*_*lum 8

Spring的Cache Abstraction不支持此行为。但是,这并不意味着不可能。支持所需的行为只需要做更多的工作。

我写了一个小例子,演示开发人员如何完成此任务。该示例使用Spring的ConcurrentMapCacheManager演示自定义。该示例将需要适合您所需的缓存提供程序(例如,Hazelcast,Coherence等)。

简而言之,您需要重写CacheManager实现的方法来“装饰” Cache。各个实现的实现情况不同。在中ConcurrentMapCacheManager,方法是createConcurrentMapCache(name:String)。在Spring Data GemFire中,您将重写getCache(name:String)方法来装饰返回的Cache。番石榴,这将是createGuavaCache(名称:字符串)GuavaCacheManager,等等。

然后,您自定义的装饰性Cache实现(可能/理想情况下,从this委托给实际的Cache impl)将处理键和相应值的缓存Collections。

这种方法有一些局限性:

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

  2. 我的实现只是一个示例,因此我选择不实现Cache.putIfAbsent(key,value)操作(此处)。

  3. 当我的实现工作时,它可以变得更强大。

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

测试类是独立的(使用Spring JavaConfig),并且可以运行而没有任何额外的依赖关系(除了Spring,JUnit和JRE)。

干杯!