繁体   English   中英

@Cacheable注释在Spring中无法正常工作

[英]@Cacheable annotation working not properly in Spring

在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按值存储。 这涉及更多,因为您需要能够复制该值。 但是它将透明地工作

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM