簡體   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