đ§ Spring Boot â Optimisation des performances avec Spring Cache
đȘ§ Introduction
Tu as dĂ©jĂ eu une API lente Ă cause de requĂȘtes rĂ©pĂ©titives en base ?
đ Exemple classique :
- Une méthode appelée 100 fois
- Qui fait toujours la mĂȘme requĂȘte
- Avec toujours le mĂȘme rĂ©sultat
Résultat :
đ„ surcharge inutile de la base
đ„ latence qui explose
đ„ scalabilitĂ© limitĂ©e
Et pourtant⊠Spring Boot propose un systÚme de cache natif ultra simple à activer.
Dans cet article, on va voir :
- Pourquoi utiliser le cache
- Comment fonctionne le cache natif de Spring Boot
- Comment lâimplĂ©menter rapidement
- Les piÚges à éviter
- Les limites (et pourquoi tu passeras peut-ĂȘtre Ă Redis plus tard)
1. ⥠Pourquoi utiliser un cache ?
Le principe est simple :
đ Ă©viter de recalculer une donnĂ©e qui ne change pas
Sans cache :
Client â Service â DB â RĂ©sultat Client â Service â DB â RĂ©sultat Client â Service â DB â RĂ©sultat
Avec cache :
Client â Service â DB â RĂ©sultat (mis en cache)
Client â Service â Cache â RĂ©sultat
Client â Service â Cache â RĂ©sultat
đŻ RĂ©sultat
âïž Moins dâappels Ă la base
âïž Temps de rĂ©ponse rĂ©duit
âïž Meilleure scalabilitĂ©
2. đ§ Spring Cache, câest quoi ?
Spring propose une abstraction simple via :
@EnableCaching
Et des annotations :
@Cacheable@CacheEvict@CachePut
đĄ Important
Elle permet de brancher facilement différents systÚmes de cache sans changer ton code métier.
Spring Boot fonctionne avec plusieurs providers de cache (EhCache, Caffeine, RedisâŠ).
Ici, on utilise le comportement par défaut, mais on verra dans un prochain article comment brancher un cache distribué comme Redis.
Par défaut :
âĄïž cache en mĂ©moire basĂ© sur une ConcurrentHashMap
3. đšâđ» Mise en place du cache
Ătape 1 â Ajouter la dĂ©pendance dans pom.xml (maven)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>
Ătape 2 â Activer le cache
@SpringBootApplication
@EnableCaching
public class Application {
}
Ătape 3 â Ajouter du cache sur une mĂ©thode
@Cacheable("users")
public User getUserById(Long id) {
simulateSlowService();
return userRepository.findById(id).orElseThrow();
}
đ Ce qui se passe :
- 1er appel â DB + mise en cache
- Appels suivants â cache direct
đ Par dĂ©faut, la clĂ© du cache
Spring utilise :clé = paramÚtres de la méthode
Ici :getUserById(1) â clĂ© = 1
4. đŻ Les annotations essentielles
đą @Cacheable
đ Met en cache le rĂ©sultat
@Cacheable("products")
public Product getProduct(Long id) { }
đŽ @CacheEvict
đ Supprime une entrĂ©e du cache
@CacheEvict(value = "users", key = "#id")<br>public void deleteUser(Long id) { }
đĄ @CachePut
đ Met Ă jour le cache sans passer par @Cacheable
@CachePut(value = "users", key = "#user.id")<br>public User updateUser(User user) { }
5. â ïž Les piĂšges classiques
1. Le cache ne fonctionne pas dans certains cas
đ Cas trĂšs frĂ©quent :
public void methodA() {
methodB(); // â cache ignorĂ©
}
@Cacheable("data")
public String methodB() { }
đ„ Pourquoi ?
âĄïž Spring utilise des proxies
âĄïž Les appels internes ne passent pas par le proxy
đ Solution :
- appeler depuis un autre bean
- ou injecter le bean lui-mĂȘme
2. Données jamais rafraßchies
đ Si tu caches sans Ă©viction : tu peux servir des donnĂ©es obsolĂštes
đ Toujours rĂ©flĂ©chir Ă :
- quand invalider ?
- quand mettre Ă jour ?
3. Mauvaise clé de cache
@Cacheable("users")
public User getUser(User user)
Mauvais si equals/hashCode mal définis
4. Cache sur des méthodes non pertinentes
Ne cache PAS :
- des données trÚs dynamiques
- des appels uniques
- des résultats énormes
6. âïž Les limites du cache natif
- Cache local uniquement
- Chaque instance a son cache
- Pas partagé entre plusieurs serveurs
- Pas de TTL natif (simple)
- Pas dâexpiration automatique facile
- Pas adapté aux architectures distribuées
- Si tu passes en microservices â problĂšme
- Perte du cache au redémarrage
7. đ§ Quand utiliser ce cache ?
âïž Bon cas
- données rarement modifiées
- lecture fréquente
- application simple (mono-instance)
â Mauvais cas
- données critiques en temps réel
- multi-instance
- besoin de synchronisation
8. đ„ Et aprĂšs ?
Quand ton application grandit, tu vas vouloir :
- un cache partagé
- une expiration (TTL)
- de la scalabilité
Câest lĂ que des solutions comme Redis entrent en jeu
9. đĄïž Bonnes pratiques
âïž Nommer clairement tes caches (users, products)
âïž Toujours prĂ©voir une stratĂ©gie dâinvalidation
âïž Ne pas cacher « par dĂ©faut » â rĂ©flĂ©chir au besoin
âïž Monitorer les performances
đ§ Conclusion
Le cache natif de Spring Boot est :
âïž Ultra simple Ă mettre en place
âïž Parfait pour dĂ©marrer
âïž TrĂšs efficace pour booster les performances
Mais :
âïž il montre vite ses limites en production avancĂ©e
Câest une excellente porte dâentrĂ©e avant de passer Ă des solutions plus robustes comme Redis.