在采用带有数组或集合参数的方法上使用Spring Cache有哪些策略? [英] What strategies exist for using Spring Cache on methods that take an array or collection parameter?

查看:559
本文介绍了在采用带有数组或集合参数的方法上使用Spring Cache有哪些策略?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use Spring's Cache abstraction to annotate methods as @Cacheable. However, some methods are designed to take an array or collection of parameters and return a collection. For example, consider this method to find entites:

public Collection<Entity> getEntities(Collection<Long> ids)

从语义上讲,我需要分别缓存Entity对象(由id键),而不是整体上基于ID的集合.类似于这个问题正在询问的问题.

Semantically, I need to cache Entity objects individually (keyed by id), not based on the collection of IDs as a whole. Similar to what this question is asking about.

简单的Spring Memcached 通过其<一个href ="https://stackoverflow.com/questions/13178723/spring-cache-abstraction-with-multi-value-queries"> ReadThroughMultiCache ,但是我想使用Spring的抽象来支持轻松更改缓存存储实现(Guava,Coherence,Hazelcast等),而不仅仅是memcached.

Simple Spring Memcached supports what I want, via its ReadThroughMultiCache, but I want to use Spring's abstraction in order to support easy changing of the cache store implementation (Guava, Coherence, Hazelcast, etc), not just memcached.

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

What strategies exist for caching this kind of method using Spring Cache?

推荐答案

Spring的缓存抽象不支持此行为.但是,这并不意味着不可能.支持所需的行为还需要做更多的工作.

Spring's Cache Abstraction does not support this behavior out-of-the-box. However, it does not mean it is not possible; it's just a bit more work to support the desired behavior.

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

I wrote a small example demonstrating how a developer might accomplish this. The example uses Spring's ConcurrentMapCacheManager to demonstrate the customizations. This example will need to be adapted to your desired caching provider (e.g. Hazelcast, Coherence, etc).

简而言之,您需要覆盖实现的方法="noreferrer">缓存.各个实现的实现情况有所不同.在ConcurrentMapCacheManager中,该方法为GuavaCacheManager中的guava/GuavaCacheManager.java#L190-L197"rel =" noreferrer> createGuavaCache(name:String),依此类推.

In short, you need to override the CacheManager implementation's method for "decorating" the Cache. This varies from implementation to implementation. In the ConcurrentMapCacheManager, the method is createConcurrentMapCache(name:String). In Spring Data GemFire, you would override the getCache(name:String) method to decorate the Cache returned. For Guava, it would be the createGuavaCache(name:String) in the GuavaCacheManager, and so on.

然后您的自定义,修饰的Cache实现(可能/理想情况下,委托给实际的

Then your custom, decorated Cache implementation (perhaps/ideally, delegating to the actual Cache impl, from this) would handle caching Collections of keys and corresponding values.

这种方法几乎没有局限性:

There are few limitations of this approach:

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

  1. A cache miss is all or nothing; i.e. partial keys cached will be considered a miss if any single key is missing. Spring (OOTB) does not let you simultaneously return cache values and call the method for the diff. That would require some very extensive modifications to the Cache Abstraction that I would not recommend.

我的实现只是一个示例,因此我选择不实现

My implementation is just an example so I chose not to implement the Cache.putIfAbsent(key, value) operation (here).

在实现过程中,可以使其变得更加健壮.

While my implementation works, it could be made more robust.

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

Anyway, I hope it provides some insight in how to handle this situation properly.

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

The test class is self-contained (uses Spring JavaConfig) and can run without any extra dependencies (beyond Spring, JUnit and the JRE).

干杯!

这篇关于在采用带有数组或集合参数的方法上使用Spring Cache有哪些策略?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆