@Cacheable注释在Spring中工作不正常

问题描述 投票:0回答:1

我在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方法返回原始数据?

提前致谢!

java spring ehcache
1个回答
1
投票

Spring缓存通过引用将结果存储在缓存中。然后,使用的缓存框架(我认为是Ehcache)将根据其配置存储结果。大多数框架默认会通过引用存储它,因为它更快。

你有2个解决方案:

  1. 代码以不可变的方式。因此,在接收地图时,只需创建一个副本,而不是在适当的位置进行修改。您可以通过将结果包装在Collections.unmodifiableMap中来确保它
  2. 告诉Ehcache按值存储。这有点涉及,因为你需要能够copy的价值。但它会透明地工作

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

© www.soinside.com 2019 - 2024. All rights reserved.