Автоматическое создание ключей 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 справочной документации, а именно в:
[...]
- Если указано больше одного параметра, верните ключ , вычисленный из хэшей всех параметров.
Чтобы предоставить другой генератор ключей по умолчанию, необходимо реализовать интерфейс org.springframework.cache.KeyGenerator
. После настройки генератор будет использоваться для каждого объявления, которое не определяет собственную стратегию генерации ключей (см. Ниже).
и ниже:
[...] аннотация @Cacheable позволяет пользователю указать способ генерации ключа через его ключевой атрибут. Разработчик может использовать SpEL для выбора интересующих аргументов [...]
И пример из документов:
@Cacheable(value="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
Поэтому в вашем случае вы должны просто реализовать equals()
и hashCode()
для FilterObject
. Достойная IDE может генерировать их для вас.