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

查看:21
本文介绍了在采用数组或集合参数的方法上使用 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.

Simple Spring Memcached 通过其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).

简而言之,您需要覆盖 CacheManager 实现的用于装饰"缓存.这因实施而异.在ConcurrentMapCacheManager中,方法是createConcurrentMapCache(name:String).在 Spring Data GemFire 中,您将覆盖 getCache(name:String) 方法来装饰返回的缓存.对于番石榴,它将是 createGuavaCache(name:String)GuavaCacheManager 中,依此类推.

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.

然后你的 自定义装饰缓存实现(也许/理想情况下,委托给实际的缓存实现,来自 this) 将处理缓存键和相应的集合值.

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.

这种方法有一些限制:

  1. 缓存未命中要么全有要么全无;即如果缺少任何单个键,则缓存的部分键将被视为未命中.Spring (OOTB) 不允许您同时返回缓存值并调用差异的方法.这将需要对我不推荐的缓存抽象进行一些非常广泛的修改.

  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.

我的实现只是一个例子,所以我选择不实现 Cache.putIfAbsent(key, value) 操作 (这里).

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天全站免登陆