Introducción a Spring Cache

Acabamos de ver como usar Java equals y hashcode

Spring Cache es una de las características de Spring Framework que nos puede sacar de más de un apuro. Habitualmente usamos Spring para crear Servicios y Repositorios que definen la parte del Modelo de nuestra aplicación. En bastantes casos nos encontramos con situaciones en las que un Servicio siempre devuelve la misma información, por ejemplo tablas paramétricas.  Es en este tipo de situaciones en las que no tiene sentido estar continuamente realizando una consulta a la base de datos ,la información no va a modificarse. Para solventar este tipo de problemas Spring aporta soluciones de Cache que permiten almacenar en memoria datos devueltos por un método concreto.

Vamos a ver el ejemplo de hola mundo para hacernos una idea. Para ello añadiremos los siguientes artefactos a nuestro proyecto Maven.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.arquitecturava</groupId>
 <artifactId>SpringCache</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>SpringCache</name>
 <dependencies>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>4.2.1.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-beans</artifactId>
 <version>4.2.1.RELEASE</version>
 </dependency>

 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>4.2.1.RELEASE</version>
 </dependency>

 </dependencies>
</project>

El siguiente paso es definir el contenido del applicationContext.xml:


<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:cache="http://www.springframework.org/schema/cache"

 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-4.0.xsd
 http://www.springframework.org/schema/cache
 http://www.springframework.org/schema/cache/spring-cache.xsd">

 <cache:annotation-driven />

 <context:component-scan base-package="com.arquitecturajava" />
 <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager"></bean>

</beans>

En este fichero se ha dado de alta uno de los tipos de Cache de SpringFramework , que pasaremos a utilizar en un Servicio.


package com.arquitecturajava;

import java.time.LocalDateTime;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class Servicio {
 public LocalDateTime fechaActual() {

 return LocalDateTime.now();

 }
}

El servicio nos devuelve la fecha y hora del sistema actual , vamos a invocarlo  desde una aplicación de consola.


package com.arquitecturajava;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Principal {

 public static void main(String[] args) {

 ClassPathXmlApplicationContext contexto= new ClassPathXmlApplicationContext("applicationContext.xml");
 Servicio s=contexto.getBean(Servicio.class);

 Thread t = new Thread (() -> {
 try {

 for (int i = 0; i < 10; i++) {
 Thread.sleep(1000);
 System.out.println(s.fechaActual());
 }

 } catch (Exception e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

 });
 t.start();
 }

}

El código del cliente invoca 10 veces al servicio y descansa 1 segundo en cada invocación. La consola muestra lo siguiente:

La información devuelta  cambia continuamente, es momento de activar la cache para el método utilizando la anotación de Spring Cache (@Cacheable) a nivel de método.


package com.arquitecturajava;

import java.time.LocalDateTime;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class Servicio {

@Cacheable("fecha")
public LocalDateTime fechaActual() {

return LocalDateTime.now();

}
}

Los datos han quedado cacheados de forma permanente. Spring Cache soporta muchas configuraciones y sistemas de cache diferentes que nos pueden ayudar aumentar el rendimiento de la aplicación.

Otros artículos relacionados:

Spring vs EJB 

Spring Anotaciones vs XML 

Spring Framework y Aislamiento