Objectif
La gestion du cache a pour objectif d'améliorer les performances au sein de l'application sans contraintes sur le développement.
...
Ces 2 méthodes se basent sur un stockage en mémoire défini par un bean cacheManager.
Déclaration Spring du cacheManager
Définition du bean cacheManager
Voici la définition du bean cacheManager :
...
La seule chose à lui définir est l'emplacement de la configuration définissant l'ensemble des caches.
Définition du ehcache
Le fichier ehcache.xml définit l'ensemble des caches utilisé dans l'application.
...
| Bloc de code |
|---|
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> |
Gestion du cache par annotation Spring
Fonctionnement
Le cache est géré par annotation. Il suffit donc d'annoter une méthode pour quelle soit gérée par le cache.
...
| Bloc de code |
|---|
public void addTraitement(final Traitement traitement) {
if (log.isDebugEnabled()) {
log.debug("entering addTraitement( " + traitement + " )");
}
daoService.addTraitement(traitement);
//flush the other instance
executeFlushCache(CacheModelConst.ACCESS_RIGHT_DEFAULT, "addTraitement");
}
|
Déclaration Spring
Fichier properties/cache/cache.xml
Le bean cacheManager déclare le fichier ehcache.xml qui décrit chaque cache.
...
Ces beans, ci-dessous, permettent d'utiliser les annotations pour vider les caches. Les "models" “models” sont définis dans un fichier de properties. Un model peut représenter plusieurs cache. (fonctionnement spécifique à ehcache) Ceci permet de vider plusieurs caches en même temps.
...
| Bloc de code |
|---|
<bean id="autoproxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <idref bean="domainService" /> <idref bean="parameterService" /> <idref bean="domainApoService" /> <idref bean="businessCacheService" /> </list> </property> <property name="interceptorNames"> <list> <value>cachingInterceptor</value> <value>flushingInterceptor</value> </list> </property> </bean> |
Fichier properties/cache.properties
Ce fichier contient la description des models pour le flush (pour vider les caches). Un model peut regrouper plusieurs cacheName ce qui permet de vider plusieurs cache lors du passage dans une méthode.
...
| Bloc de code |
|---|
Le model user vide le cache des utilisateurs et celui des pièces manquantes. user=cacheNames=fr.univ.rennes1.cri.opiR1.domain.beans.user.User,fr.univ.rennes1.cri.opiR1.domain.beans.user.candidature.MissingPiece |
Utilisation
Définition des models
Les models utilisés pour le cache et pour le flush sont identiques et sont déclarés dans une classe static : fr.univ.rennes1.cri.opiR1.web.utils.CacheModelConst
- Exemple dans la classe CacheModelConst
/** - The name of model for the domain access right cache.
- (Profile, Treatment,...)
*/
public static final String ACCESS_RIGHT_DEFAULT = "accessRight.default";* Exemple d'utilisation dans une annotation : cf ci-dessus dans la partie Fonctionnement
Gestion du cache avec ehcache
L'utilisation ad hoc du cache revient à initialiser, charger et lire "manuellement" les éléments via le cacheManager.
Initialisation du cache
Voici un exemple de code permettant l'instanciation du cache :
| Bloc de code |
|---|
/**
* The cache object for the VET.
*/
private Cache cacheVet;
// on consulte dans le cacheManager si l'entrée du cache existe déjà
if (!cacheManager.cacheExists("org.esupportail.apogee.domain.dto.enseignement.VersionEtapeDTO")) {
cacheManager.addCache("org.esupportail.apogee.domain.dto.enseignement.VersionEtapeDTO");
}
cacheVet = cacheManager.getCache("org.esupportail.apogee.domain.dto.enseignement.VersionEtapeDTO");
|
La classe Cache fait partie de la librairie net.sf.ehcache.
Chargement du cache
Une fois le cache instanciation faite, on initialise le cache avec les données qu'on souhaite stocker :
| Bloc de code |
|---|
/**
* Initialisation du cache VET.
*/
public void initCacheVet() {
// on vide le contenu du cache
cacheVet.flush();
// on prépare l'élément à stocker qui peut avoir n'importe quel format
Map<String, List<VersionEtapeDTO>> mapOfVet = new HashMap<String, List<VersionEtapeDTO>>();
...
// mise en cache des éléments de la map, la clé étant la clé dans le cache, l'élément stocké étant la liste
for (Map.Entry<String, List<VersionEtapeDTO>> vetEntry : mapOfVet.entrySet()) {
cacheVet.put(new Element(vetEntry.getKey(), vetEntry.getValue()));
}
}
|
La classe Element fait partie de la librairie net.sf.ehcache.
Lecture du cache
Lorsqu'on veut récupérer un des éléments stocké dans le cache, on procède comme suit :
| Bloc de code |
|---|
public VersionEtapeDTO getVersionEtape(final String codEtp, final Integer codVrsVet) {
// dans le cas ou le cache ne contient pas la clé
// c'est que soit l'élément n'est pas dans le cache, soit le cache a été flushé
// dans tous les cas, on réinitialise le cache
if (cacheVet.get(codEtp) == null) {
initCacheVet();
}
if (cacheVet.get(codEtp) != null) {
Element element = cacheVet.get(codEtp);
VersionEtapeDTO result = null;
// on récupère l'élément stocké dans le cache
List<VersionEtapeDTO> v = (List<VersionEtapeDTO>) element.getObjectValue();
for (VersionEtapeDTO vet : v) {
if (codVrsVet.equals(vet.getCodVrsVet())) {
result = vet;
break;
}
}
return result;
}
return null;
}
|