我正在使用KeyGenerator
在缓存组件时生成自定义键。
这是可缓存的方法:
@CachePut(value = "cacheOne", keyGenerator = "keyGenerator")
public CachedObject cacheMeta(final Object obj1,
final Object obj2,
final CachedObject cachedObject) {
return cachedObject;
}
以下是KeyGenerator
实施:
public Object generate(Object o, Method m ,Object ... params){
StringBuilder s=new StringBuilder();
return s.append(params[0].hashCode()).append(params[1].hashCode());
}
从缓存中检索值时,我生成密钥为:
StringBuilder s= new StringBuilder();
s.append(obj1.hashCode().append(obj2.hashCode()));
Element elt=CacheManager.getInstance("cacheOne").get(s)
但它总是返回null。
答案 0 :(得分:1)
问题是您使用StringBuilder
作为缓存键。 StringBuilder
未定义equals
或hashCode
。所以它依赖于Object
上定义的那些。
这基本上意味着用于获取缓存条目的get与放入条目的get匹配不匹配。
使用toString()
放置
StringBuilder s = new StringBuilder();
return s.append(params[0].hashCode()).append(params[1].hashCode()).toString();
并获取
StringBuilder s = new StringBuilder();
s.append("a".hashCode()).append("b".hashCode());
Cache.ValueWrapper wrapper = cache.get(s.toString());
解决它。
但是我要说些什么。
首先,在这里使用StringBuilder
是没用的,因为使用字符串连接会让编译器在引擎盖下添加StringBuilder
,但要更好读。所以你可以做到
return params[0].hashCode() + "" + params[1].hashCode();
和
Cache.ValueWrapper wrapper = cache.get("a".hashCode() + "" + "b".hashCode());
将完美地运作并具有相同的性能。
然后,依靠哈希码来创建密钥并不安全。 Hashcodes可能会发生冲突。即使附加两个哈希码。因此,您可以在给定密钥上混合条目。