11

有人知道 Ehcache 的默认密钥生成是如何工作的吗?如果我有以下方法:

@Cacheable(cacheName = CACHE_KEY) // CACHE_KEY is static final field.
public List<DataObject> list(
    int firstRecord, int maxRecords, int pageSize, FilterObject filter) {
    ....
}

自定义 POJO在哪里FilterObject,我应该期望什么是实际的缓存键?

我观察到的是,当使用不同的FilterObject实例而不改变我的方法调用的其他参数时,它总是产生相同的结果——第一次调用的结果被缓存并返回。

可能是FilterObjectPOJO 导致了这种行为 - 我想它要么是一些序列化,要么是.toString()问题,因为我没有覆盖相关的方法。

我仍然无法在 Ehcache 的网站和@Cacheable注释文档中找到有关如何形成这种方法的缓存键的确切信息。我将不胜感激有关此主题的任何信息和建议。

4

2 回答 2

13

这是默认的密钥生成器

public class DefaultKeyGenerator implements KeyGenerator {

public static final int NO_PARAM_KEY = 0;
public static final int NULL_PARAM_KEY = 53;

public Object generate(Object target, Method method, Object... params) {
    if (params.length == 1) {
        return (params[0] == null ? NULL_PARAM_KEY : params[0]);
    }
    if (params.length == 0) {
        return NO_PARAM_KEY;
    }
    int hashCode = 17;
    for (Object object : params) {
        hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : object.hashCode());
    }
    return Integer.valueOf(hashCode);
}

}

如您所见,它结合了每个方法参数的哈希码。

于 2012-03-15T12:07:42.363 回答
5

一切都在 Spring参考文档中进行了解释,即:

28.3.1.1 默认密钥生成

[...]

  • 如果给出了多个参数,则返回从所有参数的哈希计算的键。

要提供不同的默认密钥生成器,需要实现该org.springframework.cache.KeyGenerator接口。配置后,生成器将用于未指定自己的密钥生成策略的每个声明(见下文)。

及以下:

28.3.1.2 自定义密钥生成声明

[...] @Cacheable 注释允许用户指定如何通过其 key 属性生成密钥。开发人员可以使用 SpEL 来选择感兴趣的参数 [...]

以及来自文档的示例:

@Cacheable(value="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

因此,在您的情况下,您应该简单地实现equals()and hashCode()for FilterObject。体面的 IDE 可以为您生成它们。

于 2012-03-15T12:06:24.087 回答