Автоматическое создание ключей Ehcache и аннотация @Cacheable spring

Кто-нибудь знает, как работает генерация ключей по умолчанию для Ehcache? Если у меня есть следующий метод:

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

где FilterObject является пользовательским POJO, что я должен ожидать в качестве фактического ключа кеша?

То, что я наблюдаю, - это использование разных экземпляров FilterObject и не изменение других аргументов моего вызова метода, оно всегда дает тот же результат - результат первого вызова кэшируется и возвращается.

Возможно, это поведение FilterObject POJO вызывает поведение - я предполагаю, что это либо сериализация, либо .toString(), потому что я не переопределил соответствующие методы.

Тем не менее мне не удалось найти точной информации о том, как формируется ключ кеша для такого метода как на веб-сайте Ehcache, так и в документации по аннотации @Cacheable. Я был бы признателен за любую информацию и рекомендации по этой теме.

Ответ 1

Это генератор ключей по умолчанию

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

}

Как вы можете видеть, он объединяет хэш-коды каждого параметра метода.

Ответ 2

Все объяснено в Spring справочной документации, а именно в:

28.3.1.1 Генерация ключей по умолчанию:

[...]

  • Если указано больше одного параметра, верните ключ , вычисленный из хэшей всех параметров.

Чтобы предоставить другой генератор ключей по умолчанию, необходимо реализовать интерфейс org.springframework.cache.KeyGenerator. После настройки генератор будет использоваться для каждого объявления, которое не определяет собственную стратегию генерации ключей (см. Ниже).

и ниже:

28.3.1.2 Декларация о создании пользовательского ключа:

[...] аннотация @Cacheable позволяет пользователю указать способ генерации ключа через его ключевой атрибут. Разработчик может использовать SpEL для выбора интересующих аргументов [...]

И пример из документов:

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

Поэтому в вашем случае вы должны просто реализовать equals() и hashCode() для FilterObject. Достойная IDE может генерировать их для вас.