Declaracion cache - Tensho97/Aprende-a-Aprender GitHub Wiki

Para la declaración del cache, Spring nos provee de las siguientes anotaciones:

  • @Cacheable: almacena los datos del cache.
  • @CacheEvict: libera los datos del cache.
  • @CachePut: actualiza el cache con el resultado del método en ejecución.
  • @Caching: Agrupa múltiples operaciones de cache
  • @CacheConfig: permite configurar el cache a nivel de clase.

@Cacheable

Se utiliza para indicar que métodos requieren de cache. El resultado será almacenado para la siguiente invocación. De esta manera, ante una nueva invocación y si coinciden los argumentos, se regresa los datos almacenados de la cache sin ejecutar el método.

@Cacheable("books")
public Book findBook(ISBN isbn) {...}

Generación de clave por defecto

Dado que una cache es en esencia un almacenamiento de clave: valor, el almacenamiento del resultado necesita de su clave para el acceso. Para ello, la capa de abstracción de Spring utiliza un KeyGenerator básado en el siguiente algoritmo:

Si ningún parámetro es dado, se regresa un SimpleKey.EMPTY Si solo un parámetro es dado, retorna su instancia Si se tiene más de dos parámetros regresa el SimpleKey con todos los parámetros. Esta estrategia funciona bien en la mayoría de los casos. Se utilizan los parámetros para las clave y se implementa los métodos hashCode() y equals() para validar.

Generación de claves personalizadas

La anotación @Cacheable permite al usuario indicar como se genera la clave mediante el atributo Key. Para ello podemos utilizar SpEL para identificar los argumentos, ejecutar alguna operación o invocar métodos sin necesita de escribir codigo o implementar alguna interfaz.

@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

Condicionales

En ocasiones nos interesa limitar cuando la información de nuestro métodos va a ser recogida en la caché. Para ello se nos ofrece los párametros de condition y unless que evaluan si la expresión SpEL retorna true o false.

@Cacheable(cacheNames="book", condition="#name.length() < 32")
public Book findBook(String name)
A diferencia del parámetro condtion, la expresión contenida en unless es evaluada una vez el método ha sido llamado. De esta manera, tenemos acceso al #result

@Cacheable(cacheNames="book", condition="#name.length() < 32", unless="#result.hardback")
public Book findBook(String name)

Sincronización del cache

En entorno multi-tarea ciertas operación puede sen invocadas de manera simultanea. Por defecto. la capa de abstracción de Spring permite que un mismo valor pueda ser computados varias veces, limitando el propósito del caché.

Para estos casos, el atributo sync puede ser utilizado para bloquear una entidad en el cache mientras esta siendo manipulada. De esta manera solo una operación tiene acceso, boqueando el resto de solicitudes hasta que el cache sea actualizado

Esta característica es opcional y requiere que la implementación del CacheManager la soporte.

@Cacheable(cacheNames="foos", sync=true)
public Foo executeExpensiveOperation(String id) {...}

@CachePut

Para aquellos casos que se necesite actualizar la cache sin interferir en la ejecución del método se tiene la anotación @CachePut. El método será ejecutado y el ira a la cache. Esta anotación soporta las misma opciones que @Cacheable.

No se recomienda el uso de @CachePut y @Cacheable en el mismo método, ya que tienen comportamientos diferentes. Mientras @Cacheable hace que el método se omita mediante el uso de la mémoria caché, @CachePut siempre ejecutar el método y utiliza su resultado.

@CacheEvict

De manera contraria a @Cacheable, @CacheEvict permite limpiar los datos del cache.

Contiene un parámetro adicional allEntries que permite remover toda la cache asociada y no solo un único valor

Adicionalmente, es posible indicar si la limpieza de cache se realizara después (por defecto) o antes de la ejecución del método. Para ello se tiene el atributo beforeInvocation.

@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch)

@Caching

Para indicar múltiples cambios en la cache se utiliza la anotación @Caching

@Caching(evict = { 
    @CacheEvict("primary"), 
    @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)

@CacheConfig

@CacheConfig es una anotación a nivel de clase que nos permite configurar el nombre de la cache, indicar un KeyGenerator personalizado, señalar el CacheManager y agregar un CacheResolver personalizado

De esta manera la configuración de cache sustituirá la configuración inicial que este establecida. Sin embargo, lhay que tener presente que la configuración a nivel de método sobre escribe la @CacheConfig. Se tienen por lo tanto tres niveles para configurar las operaciones de cache:

  • De manera Global mediante el CacheManager, KeyGenerator.
  • A nivel de clase mediante @CacheConfig
  • A nivel de método.