У меня есть служба, которая вызывает внешнюю систему, чтобы получить какие-то объекты по их внешнему идентификатору, а также отправить их обратно для обновления. Вместо того, чтобы извлекать объекты по одному, существуют методы более общего назначения:
public interface ExternalSystem {
List<ExternalDTO> getObjects(List<String> externalIds);
void updateObjects(List<ExternalDTO> updates);
}
Я хотел бы поместить кеш поверх вызовов ExternalSystem, потому что они довольно дороги.
В реализации сервиса я могу просто поставить аннотации spring:
@Cacheable("cache-external")
List<ExternalDTO> getObjects(List<String> externalIds) {}
@CacheEvict(cacheNames="cache-external", allEntries=true)
void updateObjects(List<ExternalDTO> updates);
Однако такой кеш будет вести себя очень плохо, если у меня будет много пересечений между externalIds, т.е.
- Вызов # 1 getObjects ([1,2,3,4]) -> кеш, помещенный клавишей [1,2,3,4]
- Вызов # 2 getObjects ([1,2,3,4,5]) -> кеш, помещенный ключом [1,2,3,4,5]
- Вызов # 3 getObjects ([6,7,8,9]) -> кеш, помещенный ключом [6,7,8,9]
- Вызовите # 4 updateObjects (1) -> удалите все кеши, кроме третьего кеша. не содержит 3
Итак, вопрос в том, как реализовать настраиваемую стратегию (я предполагаю, что это невозможно сделать из коробки), которая вытеснит только те записи, которые действительно должны быть исключены, и сделает ключи таким образом, чтобы пересекающиеся объекты извлекались из кеша. ?
Upd. Я нашел два похожих вопроса:
- spring-cache-abstraction-with-multi-value-questions
- using- Spring-cache-on-methods-that-take-an-array-or-collection
- Spring-cacheable-methods-with-lists
Upd2. Вот что-то похожее на то, что я хочу, за исключением того, что я помещаю в кеш пары String и ExternalDTO для каждого элемента в коллекции. уровень-кеширования-элемента- список в список