Exemple de mise en cache de printemps et Ehcache
Dans ce didacticiel, nous allons vous montrer comment activer la mise en cache des données dans une application Spring et l'intégrer au frameworkEhcache populaire.
Les outils utilisés
-
Ehcache 2.9
-
Spring 4.1.4.RELEASE
-
Logback 1.0.13
-
Maven 3 / Gradle 2
-
JDK 1.7
-
Eclipse 4.4
Note
Spring prend en charge la mise en cache depuis la version 3.1
Le cache Spring a été considérablement amélioré depuis la version 4.1
1. Structure du répertoire du projet
2. Dépendances du projet
La mise en cache Spring est dans lesspring-context.jar
, pour prendre en charge la mise en cache Ehcache, vous devez également inclure lesspring-context-support.jar
.
Pour le projet Maven:
pom.xml
net.sf.ehcache ehcache 2.9.0 ch.qos.logback logback-classic 1.0.13 org.springframework spring-context 4.1.4.RELEASE org.springframework spring-context-support 4.1.4.RELEASE
Pour le projet Gradle:
gradle.build
apply plugin: 'java' apply plugin: 'eclipse-wtp' version = '1.0' // Uses JDK 7 sourceCompatibility = 1.7 targetCompatibility = 1.7 // Get dependencies from Maven central repository repositories { mavenCentral() } //Project dependencies dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' compile 'org.springframework:spring-context-support:4.1.4.RELEASE' compile 'net.sf.ehcache:ehcache:2.9.0' compile 'ch.qos.logback:logback-classic:1.0.13' }
3. Exemple Spring sans cache
Un DAO simple pour trouver un film par nom de réalisateur.
Movie.java
package com.example.movie; import java.io.Serializable; public class Movie implements Serializable { int id; String name; String directory; //getters and setters //constructor with fields //toString() }
MovieDao.java
package com.example.movie; public interface MovieDao{ Movie findByDirector(String name); }
MovieDaoImpl.java
package com.example.movie; import org.springframework.stereotype.Repository; @Repository("movieDao") public class MovieDaoImpl implements MovieDao{ //each call will delay 2 seconds, simulate the slow query call public Movie findByDirector(String name) { slowQuery(2000L); System.out.println("findByDirector is running..."); return new Movie(1,"Forrest Gump","Robert Zemeckis"); } private void slowQuery(long seconds){ try { Thread.sleep(seconds); } catch (InterruptedException e) { throw new IllegalStateException(e); } } }
AppConfig.java
package com.example.test; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({ "com.example.*" }) public class AppConfig { }
App.java
package com.example.test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.example.movie.MovieDao; public class App { private static final Logger log = LoggerFactory.getLogger(App.class); public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MovieDao obj = (MovieDao) context.getBean("movieDao"); log.debug("Result : {}", obj.findByDirector("dummy")); log.debug("Result : {}", obj.findByDirector("dummy")); log.debug("Result : {}", obj.findByDirector("dummy")); } }
Sortie
findByDirector is running... 2015-01-22 10:39:04 [main] DEBUG com.example.test.App - Result : Movie [id=1, name=Forrest Gump, directory=Robert Zemeckis] findByDirector is running... 2015-01-22 10:39:06 [main] DEBUG com.example.test.App - Result : Movie [id=1, name=Forrest Gump, directory=Robert Zemeckis] findByDirector is running... 2015-01-22 10:39:08 [main] DEBUG com.example.test.App - Result : Movie [id=1, name=Forrest Gump, directory=Robert Zemeckis]
Chaque appel àfindByDirector
prendra 2 secondes de retard.
4. Exemple de mise en cache de printemps + EhCache
Maintenant, nous allons activer la mise en cache des données sur la méthodefindByDirector
.
4.1 Create a ehcache.xml
file, to tell Ehcache how and where to cache the data.
src/main/resource/ehcache.xml
Note
Pour savoir comment configurer Ehcache, lisez cet exemple officiel deehcache.xml.
4.2 Add @Cacheable
on the method you want to cache.
MovieDaoImpl.java
package com.example.movie; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Repository; @Repository("movieDao") public class MovieDaoImpl implements MovieDao{ //This "movieFindCache" is delcares in ehcache.xml @Cacheable(value="movieFindCache", key="#name") public Movie findByDirector(String name) { slowQuery(2000L); System.out.println("findByDirector is running..."); return new Movie(1,"Forrest Gump","Robert Zemeckis"); } private void slowQuery(long seconds){ try { Thread.sleep(seconds); } catch (InterruptedException e) { throw new IllegalStateException(e); } } }
4.3 Enable Caching with @EnableCaching
and declared a EhCacheCacheManager
.
AppConfig.java
package com.example.test; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @Configuration @EnableCaching @ComponentScan({ "com.example.*" }) public class AppConfig { @Bean public CacheManager cacheManager() { return new EhCacheCacheManager(ehCacheCacheManager().getObject()); } @Bean public EhCacheManagerFactoryBean ehCacheCacheManager() { EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean(); cmfb.setConfigLocation(new ClassPathResource("ehcache.xml")); cmfb.setShared(true); return cmfb; } }
4.4 In non-web application, you need to shut down the Spring context manually, so that Ehcache got chance to shut down as well, otherwise Ehcache manager will hang there.
App.java
package com.example.test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.example.movie.MovieDao; public class App { private static final Logger log = LoggerFactory.getLogger(App.class); public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MovieDao obj = (MovieDao) context.getBean("movieDao"); log.debug("Result : {}", obj.findByDirector("dummy")); log.debug("Result : {}", obj.findByDirector("dummy")); log.debug("Result : {}", obj.findByDirector("dummy")); //shut down the Spring context. ((ConfigurableApplicationContext)context).close(); } }
Sortie
INFO: Initializing EhCache CacheManager findByDirector is running... 2015-01-22 10:53:28 [main] DEBUG com.example.test.App - Result : Movie [id=1, name=Forrest Gump, directory=Robert Zemeckis] 2015-01-22 10:53:28 [main] DEBUG com.example.test.App - Result : Movie [id=1, name=Forrest Gump, directory=Robert Zemeckis] 2015-01-22 10:53:28 [main] DEBUG com.example.test.App - Result : Movie [id=1, name=Forrest Gump, directory=Robert Zemeckis] INFO: Shutting down EhCache CacheManager
Passez en revue le temps exécuté, il n'y a pas de retard. De plus, un seul «findByDirector est en cours d'exécution…» est imprimé, car cette méthode n'est exécutée qu'une seule fois, l'appel suivant récupérera l'objet du cache.
Terminé.
More on Spring Caching
Cet article est pour vous aider à démarrer avec la mise en cache des données Spring, pour en savoir plus sur d'autres annotations de mise en cache comme@CacheEvict
,@CachePut
,@CacheConfig
et etc. , veuillez vous référer à ceSpring Cache Abstraction documentation officiel, assez détaillé là-bas.
Télécharger le code source
Téléchargez-le -Spring-Ehcache-Example.zip (20 Ko)