Caching in Spring
Imagine you have a website that shows product details. Every time a user views a product, your application queries the database. If thousands of users view the same popular product, the database gets hammered with the same query repeatedly. Caching solves this by storing frequently accessed data in memory.
Spring provides a powerful caching abstraction. You just add annotations, and Spring handles storing and retrieving data from cache.
Enable Caching:
@Configuration
@EnableCaching
public class CacheConfig {
}
Basic Caching Annotations:
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
// @Cacheable - Stores result in cache. Next call returns cached value.
@Cacheable(value = "products", key = "#id")
public Product getProductById(Long id) {
simulateSlowService();
return productRepository.findById(id).orElse(null);
}
// @CacheEvict - Removes entry from cache
@CacheEvict(value = "products", key = "#id")
public void updateProduct(Long id, Product product) {
productRepository.save(product);
}
// @CachePut - Always executes method and updates cache
@CachePut(value = "products", key = "#result.id")
public Product createProduct(Product product) {
return productRepository.save(product);
}
// Clear all entries in products cache
@CacheEvict(value = "products", allEntries = true)
public void clearAllProductsCache() {
// method body can be empty
}
private void simulateSlowService() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Multiple Cache Names:
@Cacheable({"products", "popular"})
public Product getProduct(Long id) { ... }
Conditional Caching:
// Cache only if product price > 1000
@Cacheable(value = "products", condition = "#product.price > 1000")
public Product saveProduct(Product product) { ... }
// Don't cache if result is null
@Cacheable(value = "products", unless = "#result == null")
public Product findProduct(Long id) { ... }
Cache Managers:
Spring supports various cache implementations. For development, use simple concurrent map:
@Bean
public CacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager("products", "users");
return cacheManager;
}
For production, use Redis, EhCache, or Caffeine:
// application.properties
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
Two Minute Drill
- @EnableCaching enables caching support.
- @Cacheable stores method result in cache and returns cached value on subsequent calls.
- @CacheEvict removes entries from cache (use when data changes).
- @CachePut always executes method and updates cache.
- Use key attribute to uniquely identify cache entries.
- Conditional caching with condition and unless attributes.
Need more clarification?
Drop us an email at career@quipoinfotech.com
