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

Кто-нибудь знает, как работает генерация ключей по умолчанию для 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 аннотационная документация. Буду признателен за любую информацию и рекомендации по этой теме.

2 ответа

Решение

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

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

}

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

Все объясняется в справочной документации 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 может генерировать их для вас.

Другие вопросы по тегам