2015-11-11 1 views
2

Je veux utiliser l'abstraction du cache de Spring pour annoter les méthodes comme @Cacheable. Cependant, certaines méthodes sont conçues pour prendre un tableau ou une collection de paramètres et retourner une collection. Par exemple, considérons cette méthode pour trouver ENTITES:Quelles stratégies existent pour utiliser Spring Cache sur des méthodes qui prennent un paramètre de type tableau ou collection?

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

sémantiquement, je dois cache Entity objets individuellement (par id calées), ne repose pas sur la collecte d'ID dans son ensemble. Semblable à ce que demande this question.

Simple Spring Memcached soutient ce que je veux, par l'intermédiaire de son ReadThroughMultiCache, mais je veux utiliser l'abstraction de printemps afin de soutenir un changement facile de la mise en œuvre du magasin de cache (goyave, cohérence, Hazelcast, etc.), non seulement Memcached.

Quelles stratégies existent pour mettre en cache ce type de méthode en utilisant Spring Cache?

Répondre

2

Spring's Cache Abstraction ne supporte pas ce comportement prêt à l'emploi. Cependant, cela ne signifie pas que ce n'est pas possible. c'est juste un peu plus de travail pour supporter le comportement désiré. J'ai écrit un petit example démontrant comment un développeur pourrait accomplir cela. L'exemple utilise le ConcurrentMapCacheManager de Spring pour illustrer les personnalisations. Cet exemple devra être adapté à votre fournisseur de mise en cache désiré (par exemple Hazelcast, Coherence, etc.). En bref, vous devez remplacer la méthode d'implémentation CacheManager pour "décorer" le Cache. Cela varie de la mise en œuvre à la mise en œuvre. Dans le ConcurrentMapCacheManager, la méthode est createConcurrentMapCache(name:String). Dans Spring Data GemFire, vous devez remplacer la méthode getCache(name:String) pour décorer le cache retourné. Pour Guava, ce serait le createGuavaCache(name:String) dans le GuavaCacheManager, et ainsi de suite.

Ensuite, votre custom, decorated Cache implementation (peut-être/idéalement, en délégant à la réelle Cache impl, de this) gérerait la mise en cache des collections de clés et des valeurs correspondantes.

Il y a quelques limites de cette approche:

  1. A défaut de cache est tout ou rien; c'est-à-dire que les clés partielles mises en cache seront considérées comme manquantes si une seule clé est manquante. Spring (OOTB) ne vous permet pas de retourner simultanément les valeurs du cache et d'appeler la méthode pour le diff. Cela nécessiterait des modifications très importantes de l'abstraction du cache que je ne recommanderais pas.

  2. Ma mise en œuvre est juste un exemple, j'ai donc choisi de ne pas implémenter l'opération Cache.putIfAbsent(key, value) (here). Pendant que mon implémentation fonctionne, elle pourrait être rendue plus robuste.

Quoi qu'il en soit, j'espère que cela donne un aperçu de la façon de gérer correctement cette situation.

La classe de test est autonome (utilise Spring JavaConfig) et peut s'exécuter sans aucune dépendance supplémentaire (au-delà de Spring, JUnit et JRE).

À la votre!

+0

Je devrais également souligner que si vous savez à l'avance que vous ne prévoyez pas de passer de fournisseurs de mise en cache, alors vous pouvez simplement implémenter l'opération 'Cache' en termes de fournisseur. Par exemple, si Memcached gère cela en utilisant ReadThroughMultiCache, alors vous pourriez simplement implémenter l'opération Cache.get (key) (et éventuellement, mettre?) Interms de ReadThroughMultiCache. Ma solution, cependant, a essayé d'être (pour la plupart) agnostique de fournisseur de cachette par votre description. –

+0

John, j'apprécie l'effort et l'idée, mais la limitation # 1 est un deal-breaker pour moi. Nous devons mettre en cache de manière intelligente afin que les éléments de la liste de clés ne soient PAS "tout ou rien". Nous devons utiliser les éléments mis en cache de la liste chaque fois qu'ils sont présents. –

+0

Bon, malheureusement, de prime abord, je ne peux pas imaginer une meilleure façon de rendre cela plus intelligent que de vous lier (dans une certaine mesure) sur votre fournisseur de cache sous-jacent. Quoi qu'il en soit, le framework est flexible dans la mesure où il vous donne une option pour l'extension, pour personnaliser le comportement. Cependant, out-of-the-box, ce serait très difficile à soutenir, en particulier de manière cohérente à travers les fournisseurs de mise en cache. Ouvert aux suggestions ou autres idées sur de telles questions. –