首頁 > Java > java教程 > Java Spring中關於Cache key設定注意事項

Java Spring中關於Cache key設定注意事項

黄舟
發布: 2017-10-17 09:29:27
原創
2071 人瀏覽過

本文主要對java spring-cache key配置注意事項進行了介紹,小編覺得還是挺不錯的,這裡分享給大家,供需要的朋友參考。

為了提升專案的並發效能,考慮引入本機記憶體Cache,對:外部資料來源存取、Restful API呼叫、可重複使用的複雜計算 等3種類型的函數處理結果進行快取。目前採用的是spring Cache的@Cacheable註解方式,快取具體實作選取的是Guava Cache。
具體快取的配置此處不再介紹,重點對於key的配置進行說明:

#1、基本形式


@Cacheable(value="cacheName", key"#id")  
public ResultDTO method(int id);
登入後複製

2、組合形式


@Cacheable(value="cacheName", key"T(String).valueOf(#name).concat('-').concat(#password))  
public ResultDTO method(int name, String password);
登入後複製

3、物件形式


@Cacheable(value="cacheName", key"#user.id) 
public ResultDTO method(User user);
登入後複製

4、自訂key產生器


#
@Cacheable(value="gomeo2oCache", keyGenerator = "keyGenerator") 
public ResultDTO method(User user);
登入後複製

注意:Spring預設的SimpleKeyGenerator是不會將函數名稱組合進key中的

如下:


@Component 
public class CacheTestImpl implements CacheTest { 
  @Cacheable("databaseCache") 
  public Long test1() 
  { return 1L; } 
  @Cacheable("databaseCache") 
  public Long test2() 
  { return 2L; } 
  @Cacheable("databaseCache") 
  public Long test3() 
  { return 3L; } 
  @Cacheable("databaseCache") 
  public String test4() 
  { return "4"; } 
}
登入後複製

我們期望輸出:


##

1 
2 
3 
4
登入後複製

實際卻輸出:


1 
1 
1 
ClassCastException: java.lang.Long cannot be cast to java.lang.String
登入後複製

此外,原子類型的數組,直接作為key使用也是不會生效的


##為了解決上述2個問題,自訂了一個KeyGenerator如下:

class CacheKeyGenerator implements KeyGenerator { 
  // custom cache key 
  public static final int NO_PARAM_KEY = 0; 
  public static final int NULL_PARAM_KEY = 53; 
  @Override 
  public Object generate(Object target, Method method, Object... params) { 
    StringBuilder key = new StringBuilder(); 
    key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":"); 
    if (params.length == 0) { 
      return key.append(NO_PARAM_KEY).toString(); 
    } 
    for (Object param : params) { 
      if (param == null) { 
        log.warn("input null param for Spring cache, use default key={}", NULL_PARAM_KEY); 
        key.append(NULL_PARAM_KEY); 
      } else if (ClassUtils.isPrimitiveArray(param.getClass())) { 
        int length = Array.getLength(param); 
        for (int i = 0; i < length; i++) { 
          key.append(Array.get(param, i)); 
          key.append(&#39;,&#39;); 
        } 
      } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) { 
        key.append(param); 
      } else { 
        log.warn("Using an object as a cache key may lead to unexpected results. " + 
            "Either use @Cacheable(key=..) or implement CacheKey. Method is " + target.getClass() + "#" + method.getName()); 
        key.append(param.hashCode()); 
      } 
      key.append(&#39;-&#39;); 
    } 
    String finalKey = key.toString(); 
    long cacheKeyHash = Hashing.murmur3_128().hashString(finalKey, Charset.defaultCharset()).asLong(); 
    log.debug("using cache key={} hashCode={}", finalKey, cacheKeyHash); 
    return key.toString(); 
  } 
}
登入後複製

採用此方式後可以解決:多重參數、原子型別陣列、方法名稱辨識等問題

#總結#

以上是Java Spring中關於Cache key設定注意事項的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板