2015-11-11 6 views
2

Я хочу использовать абстракцию Cache Spring, чтобы комментировать методы как @Cacheable. Однако некоторые методы предназначены для принятия массива или набора параметров и возврата коллекции. Например, рассмотрим этот метод, чтобы найти entites:Какие существуют стратегии использования Spring Cache для методов, которые принимают параметр array или collection?

public Collection<Entity> getEntities(Collection<Long> ids) 

семантически, мне нужно кэшировать Entity объекты по отдельности (в привязке по идентификатору), а не на основе сбора идентификаторов в целом. Подобно тому, о чем спрашивает this question.

Simple Spring Memcached поддерживает то, что я хочу, через его ReadThroughMultiCache, но я хочу использовать абстракцию Spring для того, чтобы поддержать легкое изменение реализации хранилища кэша (гуава, Согласованность, Hazelcast и т.д.), а не только Memcached.

Какие существуют стратегии кэширования такого метода с использованием Spring Cache?

ответ

2

Spring's Cache Abstraction не поддерживает это поведение из коробки. Однако это не означает, что это невозможно; это немного больше работы для поддержки желаемого поведения.

Я написал небольшую example, демонстрирующую, как разработчик может это выполнить. В примере используется Spring ConcurrentMapCacheManager, чтобы продемонстрировать настройки. Этот пример должен быть адаптирован к вашему желаемому поставщику кеширования (например, Hazelcast, Coherence и т. Д.).

Короче говоря, вам необходимо переопределить метод реализации CacheManager для «украшения» Cache. Это зависит от реализации и реализации. В ConcurrentMapCacheManager способ равен createConcurrentMapCache(name:String). В Spring Data GemFire ​​вы переопределите метод getCache(name:String), чтобы украсить возвращаемый кэш. Для Гуавы это будет createGuavaCache(name:String) в GuavaCacheManager и так далее.

Тогда ваш custom, decorated Cache implementation (возможно/в идеале, делегирование фактическому Cache impl, от this) будет обрабатывать кеширование Коллекций ключей и соответствующих значений.

Есть несколько ограничений этого подхода:

  1. Промах кэша это все или ничего; то есть кешированные частичные ключи будут считаться пропуском, если отсутствует какой-либо один ключ. Spring (OOTB) не позволяет одновременно возвращать значения кеша и вызывать метод для diff. Это потребует очень больших изменений в аббревиатуре Cache, которую я бы не рекомендовал.

  2. Моя реализация является лишь примером, поэтому я решил не выполнять операцию Cache.putIfAbsent(key, value) (here).

  3. Хотя моя реализация работает, ее можно сделать более надежной.

В любом случае, я надеюсь, что он дает некоторое представление о том, как правильно обращаться с этой ситуацией.

Испытательный класс является автономным (использует Spring JavaConfig) и может работать без каких-либо дополнительных зависимостей (за пределами Spring, JUnit и JRE).

Cheers!

+0

Следует также отметить, что если вы заранее знаете, что вы не планируете переключать поставщиков кэширования, вы можете просто реализовать операцию «Cache» с точки зрения поставщика. Например, если Memcached обрабатывает это с помощью ReadThroughMultiCache, тогда вы можете просто реализовать операции Cache.get (key) (и, возможно, put?) Для ReadThroughMultiCache. Мое решение, однако, пыталось (в основном) кэшировать провайдера агностиком за ваше описание. –

+0

Джон, я ценю усилия и идеи, но ограничение №1 для меня - это разбойник. Нам нужно кэшировать разумно, чтобы элементы в списке ключей НЕ были «все или ничего». Нам нужно использовать кешированные элементы из списка, когда они присутствуют. –

+0

Правильно, к сожалению, с моей головы, я не могу придумать лучшего способа сделать это более умным, чем привязать себя (в определенной степени) к вашему базовому поставщику кеширования. Во всяком случае, структура гибкая, поскольку она дает вам возможность расширения, чтобы настроить поведение. Однако, из-за-коробки, это будет очень сложно поддерживать, особенно последовательно через поставщиков кеширования. Открыта для предложений или других идей по таким вопросам. –

Смежные вопросы