GUIDE MISE EN CACHE AVECSPRING-BOOT
Dans cet article, nous allons examiner la prise en charge de la mise en cache dans Spring boot, comment la configurer et l’utiliser pour mettre en cache des objets, mettre à jour le cache et supprimer des objets du cache.Qu'est-ce que la mise en cache ?
La mise en cache consiste à stocker des objets ou des données dans une zone séparée. Cette zone est appelée cache. Le cache peut être une base de données, en mémoire, un serveur, selon l’implémentation.Lorsque la mise en cache est activée, l’application recherche d’abord l’objet requis dans le cache au lieu de l’extraire de la base de données ou du magasin de données réel. Si elle ne trouve pas l’objet dans le cache, elle accède alors à la base de données.La mise en cache est utilisée pour accélérer l’accès aux données, car l’objet ou les données ne sont récupérés dans la base de données que la première fois qu’ils sont nécessaires. Par la suite, il est récupéré dans le cache et la base de données n’est pas consultée. Ainsi, la mise en cache améliore les performances d’une application.Cache de Spring
Spring boot prend en charge la mise en cache. Vous pouvez utiliser n’importe quel fournisseur decache externe pour mettre en cache des objets.Voici le flux de contrôle d’une application Spring boot avec la mise en cache activée.
Si Spring boot ne détecte aucun fournisseur de cache, il utilise ConcurrentHashMap pour stocker les données. L’utilisation du fournisseur de cache par défaut n’est pas recommandée en production, mais elle est suffisante pour comprendre la mise en cache de Spring boot.Voici les fournisseurs de cache pris en charge par la mise en cache de Spring boot- JCache(EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple
Une configuration séparée est requise si l’un de ces fournisseurs de cache est utilisé. Cet articlene couvre que le support de la mise en cache par défaut de Spring boot.
Configuration du cache de Spring
Pour ajouter le support de la mise en cache de Spring boot, vous devez ajouter la dépendance suivante au projet. Cela ajoutera les jars correspondants au classpath.Annotations du cache de Spring
Voici les annotations dont vous avez besoin pour ajouter le support de la mise en cache àl’application Spring boot.
1. @EnableCachingCette annotation est utilisée pour informer Spring boot que nous voulons utiliser la mise en cachedans cette application.Cette annotation peut être appliquée sur la classe principale de Spring boot comme indiqué cidessous.
@SpringBootApplication
@ComponentScan(“com.ebenyx.template.jsf”)
@EnableCaching
public class CachingApplication {
public static void main(String[] args) {
SpringApplication.run(CachingApplication.class,
args);
}
}
On peut aussi l’appliquer sur une classe de configuration Spring comme ci-dessous.
@Configuration
@EnableCaching
public class AppConfig { }
Si vous utilisez le CacheManager par défaut et que vous ne souhaitez pas le personnaliser, il n’est
pas nécessaire de créer une classe distincte pour appliquer @EnableCachingLe gestionnaire de cache par défaut peut être personnalisé en utilisant un bean
CacheManagerCustomizer comme indiqué ci-dessous.
Dans ce cas, vous pouvez créer une classe @Configuration distincte et y appliquer
@EnableCaching.
@Configuration
@EnableCaching
public class CacheConfigurer {
@Bean
public
CacheManagerCustomizer<ConcurrentMapCacheManager>
cacheManagerCustomizer() {
return new
CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager
cacheManager) {
cacheManager.setAllowNullValues(false);
}
};
}
}
Ce code ne permettra pas la mise en cache des valeurs nulles.
Vous pouvez également créer une classe qui implémente l’interface CacheManagerCustomizer et
implémenter sa méthode customize().Ainsi, le code ci-dessus peut également être remplacé par
@Component
@EnableCaching
public class CacheCustomizer implements
CacheManagerCustomizer<ConcurrentMapCacheManager> {
@Override
public void customize(ConcurrentMapCacheManager
cacheManager) {
cacheManager.setAllowNullValues(false);
}
}
MAIS, tout cela n’est pas nécessaire si vous ne voulez pas de personnalisation. Ajoutez
simplement @EnableCaching sur la classe principale et vous êtes prêt à partir.
@Configuration
@EnableCaching
public class CacheConfigurer {
@Bean
public
CacheManagerCustomizer<ConcurrentMapCacheManager>
cacheManagerCustomizer() {
return new
CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager
cacheManager) {
cacheManager.setAllowNullValues(false);
}
};
}
}
2. @EnableCachingAprès avoir informé Spring que nous devons prendre en charge la mise en cache, nous devons
indiquer quels objets nous voulons mettre en cache.
Pour ce faire, nous utilisons l’annotation @Cacheable.
Cette annotation est appliquée sur une méthode et la valeur de retour de cette méthode est
automatiquement mise en cache par Spring.
Si elle est appliquée à une classe, elle ajoute un comportement de mise en cache à toutes les
méthodes de cette classe et les valeurs de retour de toutes les méthodes sont mises en cache.
Exemple,
@Cacheable("posts")
public Post findById(Integer postId) {
// fetch post from database
}
Lorsqu’une demande de récupération d’un message arrive, Spring boot va le chercher dans le
cache nommé « posts ».
Si le message est trouvé dans le cache, alors cette méthode ne sera pas invoquée. Dans le cas
contraire, cette méthode sera appelée et la base de données sera accédée pour récupérer le
message.Cela signifie également que pour la première fois, cette méthode sera invoquée puisque le
message ne sera pas présent dans le cache.Le nom du cache est obligatoire, sinon l’application échouera au moment de l’exécution avec une
java IllegalStateException.Tous les objets sont mis en cache en fonction d’une clé. Si aucune clé n’est spécifiée, alors les
paramètres de la méthode sont utilisés pour créer une clé.
3. @CachePutLes objets mis en cache sont des copies des objets originaux dans la base de données et doivent
être identiques à ceux-ci. Lorsque l’objet original est modifié, l’objet mis en cache doit également
être mis à jourCeci est fait en utilisant l’annotation @CachePut et est appliqué sur la méthode qui
effectue l’opération de mise à jour. Exemple,
@CachePut("posts")
public void updatePost(Post post){
// update post object
}
@CachePut possède les mêmes attributs que @Cacheable tels que la valeur, la clé, la condition,etc., et ils se comportent de la même manière en ce qui concerne l’opération de mise à jour
4. @CacheEvictCette annotation est utilisée pour indiquer une opération de suppression des données du cacheet est appliquée sur la méthode qui supprime l’objet de la base de données comme indiqué cidessous.
@CacheEvict("posts")
public void deletePost(Integer postId) {
// delete post object
}
Là encore, @CacheEvict possède les mêmes attributs que @Cacheable tels que la valeur, la clé, lacondition, etc., et ils se comportent de la même manière en ce qui concerne l’opération desuppression.
5. @CacheConfigSi les annotations de cache sur toutes les méthodes d’une classe partagent les mêmes propriétés telles que le nom du cache, le gestionnaire de cache, etc., alors au lieu de dupliquer ces valeurs dans toutes les annotations, vous pouvez utiliser l’annotation @CacheConfig.Celle-ci est utilisée au niveau de la classe et contient des propriétés telles que cacheNames, keyGenerator, cacheManager et cacheResolver. Exemple,@Service
@CacheConfig(cacheNames="posts")
public class PostService {
@Cacheable
public Post findById(Integer postId) { }
}
Notez que maintenant @Cacheable ne définit pas de nom de cache, il est pris de @CacheConfig à
la place.
Attribut unlessAvec Spring boot, nous pouvons choisir de mettre en cache un objet récupéré dans la base de
données en fonction d’une condition.
Avec @CachePut, nous avons une propriété unless qui indique à Spring boot de mettre en cache
l’objet seulement s’il correspond à une certaine condition.
SpEL fournit une variable contextuelle #result qui fait référence à l’objet qui est récupéré lorsque
cette méthode est appelée et vous pouvez appliquer une condition sur ses valeurs.
La méthode ci-dessous mettra en cache le titre uniquement s’il comporte plus de 50 caractères
ou si le titre comporte moins de 50 caractères.
@CachePut(value="titles", unless="#result.length() < 50")
public String getTitle(Post post) {
// fetch post with given id
}
unless nous permet de mettre en cache des objets sur la base de la sortie, contrairement à lacondition qui effectue la mise en cache sur la base de l’entrée.N’oubliez pas que l’attribut unless n’est disponible qu’avec @CachePut.
package com.codippa;
import org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootApplicat
ion;
import
org.springframework.cache.annotation.EnableCaching;
import
org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.codippa")
public class CachingApplication {
public static void main(String[] args) {
SpringApplication.run(CachingApplication.class,
args);
}
}
package com.codippa;
public class Post {
private Integer postId;
private String title;
/**
* Constructor
*/
public Post(Integer postId, String title) {
this.postId = postId; this.title = title;
}
// getter and setter methods
}
Controller class
package com.codippa;
import org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.DeleteMapping;
import
org.springframework.web.bind.annotation.GetMapping;
import
org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.PostMapping;
import
org.springframework.web.bind.annotation.ResponseBody;
import
org.springframework.beans.factory.annotation.Autowired;
@Controller
public class PostController {
@Autowired PostService service;
@GetMapping("/posts/{id}")
public @ResponseBody Post findById(@PathVariable("id")
Integer postId) {
return service.findById(postId);
}
@PostMapping("/updatepost")
public void updatePost(Post post) {
service.updatePost(post);
}
@DeleteMapping("/posts/{id}")
public void deleteById(@PathVariable("id") Integer
postId) {
service.deleteById(postId);
}
}
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class PostService {
@Cacheable("posts")
public Post findById(Integer postId) {
System.out.println("#### Fetching Post ######");
return new Post(postId, "Demo post");
}
@CachePut("posts")
public void updatePost(Post post) {
// update post
}
@CacheEvict("posts")
public void deleteById(Integer postId) {
// delete post
}
}
Pour vérifier que la mise en cache fonctionne,
cliquez sur URL,
http://localhost:8080/posts/1 et regardez la console.
Elle devrait afficher
#### Fetching Post ######
Lorsque vous taper la même URL à plusieurs reprises, ce message ne sera pas imprimé. Cela signifie que la méthode n’est pas invoquée après la première fois. Maintenant, changez le post id et le message s’imprimera pour la première fois.Notez qu’il s’agit d’une application web Spring boot et que pour que cela fonctionne, vous devez également ajouter la dépendance du démarreur web Spring boot dans les fichiers pom.xml ou build.gradle. Pour configurer une application web avec Spring boot, référez-vous à cet article. Avec la mise en cache par défaut de Spring boot, vous ne pouvez pas définir de délai d’expiration ou de durée de vie pour les données mises en cache, après quoi les objets seront automatiquement supprimés du cache. Si vous souhaitez bénéficier de cette fonctionnalité, utilisez un fournisseur de cache externe tel que ehcache ou l’un de ceux énumérés ci-dessus. Ces fournisseurs peuvent être configurés pour l’expiration automatique des données mises en cache.J’espère que cet article vous a été utile. Pour lire l’article original et complet, référez-vous à ce lienhttps://ihorkosandiak.medium.com/spring-boot-caching-d74591abe117