簡單理解自定義 KeyGenerator

站在用戶的角度思考問題,與客戶深入溝通,找到興慶網(wǎng)站設(shè)計(jì)與興慶網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋興慶地區(qū)。
一般情況我們在 spring boot 中會(huì)使用 redis 作為緩存 但我們是需要自定義 cache key 的生成方式
1.為什么不使用 spring 默認(rèn)的 生成策略?
先看看源碼:
public class DefaultKeyGenerator implements KeyGenerator {
public static final int NO_PARAM_KEY = 0;
public static final int NULL_PARAM_KEY = 53;
public DefaultKeyGenerator() {
}
public Object generate(Object target, Method method, Object... params) {
if (params.length == 0) {
//沒有參數(shù)直接返回 0
return 0;
} else {
if (params.length == 1) {
Object param = params[0];
if (param == null) {
//有一個(gè)參數(shù) 并且為 null 返回 53
return 53;
}
//參數(shù)不是數(shù)組 直接返回參數(shù)
if (!param.getClass().isArray()) {
return param;
}
}
//其它情況 返回 深度計(jì)算的 hashcode 簡單理解可以認(rèn)為就是一個(gè) hashcode
return Arrays.deepHashCode(params);
}
}
}DefaultKeyGenerator 最終返回的 緩存鍵值當(dāng)參數(shù)列表的值相同時(shí)是一樣的 這樣就會(huì)造成獲取到錯(cuò)誤的緩存數(shù)據(jù)
spring 還有一個(gè) 生成策略 同樣也是有這樣的 問題
public class SimpleKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return generateKey(params);
}
/**
* Generate a key based on the specified parameters.
*/
public static Object generateKey(Object... params) {
if (params.length == 0) {
return SimpleKey.EMPTY;
}
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return param;
}
}
return new SimpleKey(params);
}
}
public class SimpleKey implements Serializable {
public static final SimpleKey EMPTY = new SimpleKey();
private final Object[] params;
private final int hashCode;
/**
* Create a new {@link SimpleKey} instance.
* @param elements the elements of the key
*/
public SimpleKey(Object... elements) {
Assert.notNull(elements, "Elements must not be null");
this.params = new Object[elements.length];
System.arraycopy(elements, 0, this.params, 0, elements.length);
this.hashCode = Arrays.deepHashCode(this.params);
}
@Override
public boolean equals(Object obj) {
return (this == obj || (obj instanceof SimpleKey
&& Arrays.deepEquals(this.params, ((SimpleKey) obj).params)));
}
@Override
public final int hashCode() {
return this.hashCode;
}
@Override
public String toString() {
return getClass().getSimpleName() + " [" + StringUtils.arrayToCommaDelimitedString(this.params) + "]";
}
}最后 cache key 使用的是這個(gè)
return getClass().getSimpleName() + " [" + StringUtils.arrayToCommaDelimitedString(this.params) + "]";這也會(huì)在一定的情況下出現(xiàn)獲取到錯(cuò)誤的緩存數(shù)據(jù)
所以我們需要自己自定義 cache key 的生成方式
我一般是這樣用的 類名+方法名+參數(shù)列表的類型+參數(shù)值 再做 哈希散列 作為key
@Bean
public KeyGenerator myKeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
sb.append("&");
for (Object obj : params) {
if (obj != null){
sb.append(obj.getClass().getName());
sb.append("&");
sb.append(JSON.toJSONString(obj));
sb.append("&");
}
}
log.info("redis cache key str: "+sb.toString());
log.info("redis cache key sha256Hex: "+DigestUtils.sha256Hex(sb.toString()));
return DigestUtils.sha256Hex(sb.toString());
}
};
}
分享名稱:springbootcacheredis簡單理解自定義KeyGenerator
分享路徑:http://www.chinadenli.net/article48/gpcgep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、企業(yè)網(wǎng)站制作、云服務(wù)器、網(wǎng)頁設(shè)計(jì)公司、自適應(yīng)網(wǎng)站、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)