Introdução: Por que usar cache em Java?
\nNo desenvolvimento moderno de alta carga, a velocidade de acesso aos dados é um fator crítico. Cada requisição ao banco de dados ou API externa aumenta o tempo de resposta e a carga na infraestrutura. Cache em Java permite armazenar dados frequentemente solicitados na memória de alto desempenho (RAM), reduzindo o tempo de resposta de dezenas de milissegundos para microssegundos.
\nNeste artigo, abordaremos três abordagens principais para cache: soluções embutidas (HashMap, Caffeine, Ehcache), Redis e Memcached. Você aprenderá como escolher a ferramenta adequada e verá exemplos de código funcionais.
\n\n1. Soluções embutidas para cache em Java
\nPara projetos pequenos ou aplicações single-thread, coleções embutidas geralmente são suficientes. No entanto, para ambientes de produção, é melhor usar bibliotecas especializadas.
\n\n1.1. Cache simples com HashMap
\nA maneira mais simples é usar ConcurrentHashMap com gerenciamento manual de tempo de vida. Adequado para protótipos, mas não possui mecanismos de despejo (eviction).
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 de alto desempenho para Java
\nCaffeine é uma biblioteca moderna, usada no Spring Cache. Suporta despejo automático por tempo, tamanho e frequência de uso.
\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", "Alexey");\n String user = cache.getIfPresent("user_1");\n System.out.println(user); // Alexey\n }\n}\n\n1.3. Ehcache — padrão corporativo
\nEhcache é uma solução madura com suporte a clusterização e persistência em disco. Frequentemente usado em conjunto com 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 — cache distribuído para Java
\nRedis é um armazenamento de dados in-memory que funciona como um serviço separado