从春天文档 :
@Cacheable(value="bookCache", key="isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
如何指定@Cachable
使用isbn
和checkWarehouse
为重点?
从春天文档 :
@Cacheable(value="bookCache", key="isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
如何指定@Cachable
使用isbn
和checkWarehouse
为重点?
更新 :当前弹簧Cache实现用所有的方法参数作为缓存键,除非另有说明。 如果你想使用选择键,指阿尔扬的回答 ,它使用规划环境地政司名单{#isbn, #includeUsed}
这是创建唯一键的最简单方式。
从Spring文档
默认键生成策略与Spring 4.0的发布改变了。 春天的早期版本使用一键生成策略,对于多个关键参数,只考虑的参数,而不是equals()方法中的hashCode(); 这可能会导致意外键冲突(见SPR-10237为背景)。 新的“SimpleKeyGenerator”用来这样的场景复合键。
春节前4.0
我建议你的东西,如Concat的在SpeI位表达的参数值, key="#checkWarehouse.toString() + #isbn.toString()")
我相信这应该org.springframework.cache.interceptor.ExpressionEvaluator工作返回Object,稍后用作键,这样你就不必提供int
在SPEL表达。
至于高碰撞概率的哈希码-你不能用它作为重点。
有人在这个线程建议使用T(java.util.Objects).hash(#p0,#p1, #p2)
但它不会工作,这种做法很容易被破解,例如我用从数据SPR-9377 :
System.out.println( Objects.hash("someisbn", new Integer(109), new Integer(434)));
System.out.println( Objects.hash("someisbn", new Integer(110), new Integer(403)));
两条线打印-636517714在我的环境。
PS其实参考文档中,我们有
@Cacheable(value="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
我认为,这个例子是错误的,误导性的,应该从文件中删除,因为键应该是唯一的。
PPS还看到https://jira.springsource.org/browse/SPR-9036了解有关的默认密钥生成一些有趣的想法。
我想补充的正确性着想,作为一个有趣的事实,使用安全的加密哈希函数像SHA256,由于这类函数的性质这个任务是可能的,但要计算它的每一次可能是太昂贵了。
与Spring 3.2的一些有限的测试后,似乎可以使用一个规划环境地政司列表: {..., ..., ...}
这还可以包括null
值。 春天传递列表为重点,以实际的缓存实现。 当使用的Ehcache,这样会在某个时候调用列表#hashCode()方法 ,这需要所有的项目考虑在内。 (我不知道如果只的Ehcache依赖于哈希码。)
我用这个共享的高速缓存,其中我有方法名的关键,以及,这春天的默认密钥生成器不包括 。 这样我可以很容易地擦拭(单)高速缓存,没有(太多...)冒险匹配的密钥对不同的方法。 喜欢:
@Cacheable(value="bookCache",
key="{ #root.methodName, #isbn?.id, #checkWarehouse }")
public Book findBook(ISBN isbn, boolean checkWarehouse)
...
@Cacheable(value="bookCache",
key="{ #root.methodName, #asin, #checkWarehouse }")
public Book findBookByAmazonId(String asin, boolean checkWarehouse)
...
当然,如果许多方法都需要这一点,你总是使用所有参数的关键,那么人们也可以自定义一个密钥生成器包含的类和方法名:
<cache:annotation-driven mode="..." key-generator="cacheKeyGenerator" />
<bean id="cacheKeyGenerator" class="net.example.cache.CacheKeyGenerator" />
...有:
public class CacheKeyGenerator
implements org.springframework.cache.interceptor.KeyGenerator {
@Override
public Object generate(final Object target, final Method method,
final Object... params) {
final List<Object> key = new ArrayList<>();
key.add(method.getDeclaringClass().getName());
key.add(method.getName());
for (final Object o : params) {
key.add(o);
}
return key;
}
}
您可以在JDK 1.7使用一个Spring-EL表达式,如:
@Cacheable(value="bookCache", key="T(java.util.Objects).hash(#p0,#p1, #p2)")
这将工作
@Cacheable(value="bookCache", key="#checkwarehouse.toString().append(#isbn.toString())")
用这个
@Cacheable(value="bookCache", key="#isbn + '_' + #checkWarehouse + '_' + #includeUsed")