Introduction : Pourquoi la mise en cache en Java est-elle nécessaire ?
\nDans le développement moderne à forte charge, la vitesse d'accès aux données est un facteur critique. Chaque requête à une base de données ou à une API externe augmente le temps de réponse et la charge sur l'infrastructure. La mise en cache en Java permet de stocker les données fréquemment demandées dans une mémoire rapide (RAM), réduisant le temps de réponse de dizaines de millisecondes à des microsecondes.
\nDans cet article, nous aborderons trois approches principales de la mise en cache : les solutions intégrées (HashMap, Caffeine, Ehcache), Redis et Memcached. Vous apprendrez comment choisir l'outil approprié et verrez des exemples de code fonctionnels.
\n\n1. Solutions intégrées pour la mise en cache en Java
\nPour les petits projets ou les applications monothread, les collections intégrées sont souvent suffisantes. Cependant, pour un environnement de production, il est préférable d'utiliser des bibliothèques spécialisées.
\n\n1.1. Cache simple avec HashMap
\nLa façon la plus simple est d'utiliser ConcurrentHashMap avec une gestion manuelle de la durée de vie. Convient aux prototypes, mais ne dispose pas de mécanismes d'éviction.
import java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.TimeUnit;\n\npublic class SimpleCache {\n private final ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();\n\n public void put(String key, Object value, long ttlMs) {\n cache.put(key, new CacheEntry(value, System.currentTimeMillis() + ttlMs));\n }\n\n public Object get(String key) {\n CacheEntry entry = cache.get(key);\n if (entry == null || System.currentTimeMillis() > entry.expiry) {\n cache.remove(key);\n return null;\n }\n return entry.value;\n }\n\n private record CacheEntry(Object value, long expiry) {}\n}\n\n1.2. Caffeine — cache haute performance pour Java
\nCaffeine est une bibliothèque moderne utilisée dans Spring Cache. Elle prend en charge l'éviction automatique basée sur le temps, la taille et la fréquence d'utilisation.
\nimport com.github.benmanes.caffeine.cache.Cache;\nimport com.github.benmanes.caffeine.cache.Caffeine;\nimport java.util.concurrent.TimeUnit;\n\npublic class CaffeineExample {\n public static void main(String[] args) {\n Cache<String, String> cache = Caffeine.newBuilder()\n .expireAfterWrite(10, TimeUnit.MINUTES)\n .maximumSize(1000)\n .build();\n\n cache.put("user_1", "Alexei");\n String user = cache.getIfPresent("user_1");\n System.out.println(user); // Alexei\n }\n}\n\n1.3. Ehcache — standard d'entreprise
\nEhcache est une solution mature avec prise en charge du clustering et de la persistance sur disque. Elle est souvent utilisée en combinaison avec Hibernate.
\nimport org.ehcache.Cache;\nimport org.ehcache.CacheManager;\nimport org.ehcache.config.builders.CacheConfigurationBuilder;\nimport org.ehcache.config.builders.CacheManagerBuilder;\nimport org.ehcache.config.builders.ResourcePoolsBuilder;\n\npublic class EhcacheExample {\n public static void main(String[] args) {\n CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()\n .withCache("users",\n CacheConfigurationBuilder.newCacheConfigurationBuilder(\n String.class, String.class,\n ResourcePoolsBuilder.heap(100))\n ).build();\n cacheManager.init();\n\n Cache<String, String> cache = cacheManager.getCache("users", String.class, String.class);\n cache.put("user_2", "Maria");\n System.out.println(cache.get("user_2")); // Maria\n\n cacheManager.close();\n }\n}\n\n2. Redis — mise en cache distribuée pour Java
\nRedis est un magasin de données en mémoire fonctionnant comme un serveur distinct.