@Cacheable注释在春季无法正常工作



我在 Spring 中使用@Cacheable注释时遇到了奇怪的行为。我有一个标记为 @Cacheable 的方法并返回 Map:

//dao layer
@Cacheable(value = "Cache1")
public Map<String, String> getNamesByDateAndCurrency(LocalDate date, String currency) {
    // Returns some map
}

我从以下方法调用此方法,并使用retainAll()方法更改映射:

//service layer
@Autowired
private DaoImpl dao;
...
@Cacheable( value = "Cache2")
public List<Integer> getUUIDs(Integer requestNumber, Set<String> set) {
   //some code..
   Map<String, String> names = dao.getNamesByDateAndCurrency(params..);
   names.keySet().retainAll(set);
   //some other code, no any changes of map in further
}
dao.getNamesByDateAndCurrency(params..)表达式在我使用相同的

参数再次调用此方法时,表达式将返回缓存的数据。

问题是getNamesByDateAndCurrency方法正在缓存执行retainAll方法后更改的数据。

我的问题是为什么外部操作(retainAll(方法会影响缓存的响应?为什么它没有从getNamesByDateAndCurrency方法返回原始数据?

提前感谢!

Spring 缓存

通过引用将结果存储在缓存中。然后,使用的缓存框架(我认为在您的例子中是 Ehcache(将根据其配置存储结果。默认情况下,大多数框架将通过引用来存储它,因为它要快得多。

您有 2 个解决方案:

  1. 以不可变的方式编码。因此,在接收地图时,只需创建副本即可,而不是就地修改地图。您可以通过将结果包装在Collections.unmodifiableMap中来确保它
  2. 告诉 Ehcache 按值存储。这有点复杂,因为您需要能够复制值。但它会透明地工作

请注意,无论数据存储在堆上、磁盘上还是群集上,默认情况下它都会按预期工作。因为所有这些选项都需要复制键和值。只有堆上具有"按引用"存储优化。

最新更新