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.