Java Ehcache 自动密钥生成和@Cacheable spring 注释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9719067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:39:55  来源:igfitidea点击:

Ehcache automatic key generation and @Cacheable spring annotation

javaspringehcachepojomethod-parameters

提问by Ivaylo Slavov

Does anybody know how the default key generation for Ehcache works? If I have the following method:

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

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

where FilterObjectis a custom POJO, what should I expect to be the actual cache key?

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

What I am observing is when using different FilterObjectinstances and not changing the other argumentsof my method call, it always produces the same result - the first call's result is cached and returned.

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

Probably it is the FilterObjectPOJO which causes the behaviour - I suppose it is either some serialization, or .toString()issue, because I haven't overridden the relevant methods.

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

Still I was unable to find exact information on how the cache key for such method is being formed both in Ehcache's website and in the @Cacheableannotation documentation. I'd appreciate any information and recommendations on this topic.

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

采纳答案by pap

This is the default key generator

这是默认的密钥生成器

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);
}

}

As you can see, it combines the hash-codes of each method parameter.

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

回答by Tomasz Nurkiewicz

Everything is explained in Spring reference documentation, namely in:

Spring参考文档中解释了所有内容,即:

28.3.1.1 Default Key Generation:

28.3.1.1 默认密钥生成

[...]

  • If more the one param is given, return a key computed from the hashes of all parameters.

To provide a different default key generator, one needs to implement the org.springframework.cache.KeyGeneratorinterface. Once configured, the generator will be used for each declaration that doesn not specify its own key generation strategy (see below).

[...]

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

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

and below:

及以下:

28.3.1.2 Custom Key Generation Declaration:

28.3.1.2 自定义密钥生成声明

[...] the @Cacheable annotation allows the user to specify how the key is generated through its key attribute. The developer can use SpEL to pick the arguments of interest[...]

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

And an example from the docs:

以及文档中的一个示例:

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

So in your case you should simply implement equals()and hashCode()for FilterObject. Decent IDE can generate them for you.

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