当在返回列表的方法上放置Spring的@Cacheable注解时,它会做什么?

19

我已经在网上到处寻找上述问题的简单答案,但就是找不到。我的方法如下:

@Cacheable(cacheNames = "objects")
public List<Object> get() { .. }

我正在使用EhCache 2.10.0和Spring Framework 4.2.1,并且我可以看到此方法的以下输出:

Adding cacheable method 'get' with attribute: [CacheableOperation[public java.util.List com.example.DAO.get()] caches=[objects] | key='' ...

同样也适用于后期记录。

Computed cache key 'SimpleKey []' for operation ...

@Cacheable注解在这种情况下应该做什么?是将每个对象放入以hashCode为键的缓存中(如其他地方所提示)?还是将整个列表按照某些基于列表的hashCode直接放入缓存中?

1个回答

11
Spring文档提到:
由于缓存本质上是键值存储,因此每次调用缓存的方法都需要将其转换为适合缓存访问的键。Out of the box,缓存抽象使用一个基于以下算法的简单KeyGenerator:
- 如果没有给定参数,则返回 SimpleKey.EMPTY。 - 如果只有一个参数,则返回该实例。 - 如果给定了多个参数,则返回从所有参数的哈希计算而来的键。
链接:https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/integration.html#cache 当您使用 @Cacheable(cacheNames = "objects") 注释它时,您会为其指定一个可以识别缓存的缓存名称。由于您的方法没有任何参数,因此对于缓存名称为“objects”的情况,它将已经缓存了返回对象(在这种情况下,是 List<Object> )。每次调用该方法时,它都将检查具有cacheName对象和key值为'0'的缓存。如果它之前已经有被缓存的返回对象,它将返回该对象。
更新:对于Spring 4+,使用 SimpleKey.EMPTY 作为无参数的键。

那么在第二次调用get()方法时,它会返回整个列表? - ben3000
2
是的,它会。因为该方法已经被执行并且对象已被缓存。请注意您的方法必须是公共的才能起作用。 - Karthik R
3
列表中的单个对象是否可以在不同的键下进行缓存? - ben3000
1
该方法的“Result”实际上被缓存了。这意味着缓存不是针对对象的,而是针对方法名称及其参数(正如Java文档所示),并且该方法的结果也被缓存了。它不关心对象的类型,只缓存结果“Object”。 - Karthik R
1
Spring 4.0+ 返回 SimpleKey.EMPTY 而不是0,因此对我的应用程序输出非常有帮助,但无论如何都很有用。 - ben3000
我希望找到一种方法,除了缓存完整列表之外,还可以按ID将每个对象添加到单独的缓存中,但是在Spring缓存中似乎没有这样的方法。 - Steve Bauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接