Caching with Spring Boot (@Cacheable)


Table of Contents

  1. Introduction to Caching in Spring Boot
  2. Benefits of Caching
  3. Setting Up Caching in Spring Boot
  4. Understanding @Cacheable Annotation
  5. Caching Providers in Spring Boot
  6. Cacheable Methods and Cache Names
  7. Cache Eviction and Expiration
  8. Advanced Caching Features (e.g., @CachePut, @CacheEvict)
  9. Troubleshooting Caching Issues
  10. Summary

1. Introduction to Caching in Spring Boot

Caching is an essential concept in application performance optimization. It allows you to store frequently accessed data in memory, thereby reducing the load on underlying resources such as databases or external services. In Spring Boot, caching can be easily enabled and configured using Spring’s powerful caching abstraction.

Spring provides a simple yet flexible mechanism for caching with annotations like @Cacheable, @CachePut, and @CacheEvict. This module will explore how to use these annotations and configure caching effectively in your Spring Boot application.


2. Benefits of Caching

  • Improved Performance: Reduces the need to fetch data repeatedly from a database or make external API calls by caching results.
  • Reduced Latency: Fetching data from memory is much faster than querying a database or external service.
  • Scalability: Cache helps to reduce the load on critical resources, making your application more scalable.
  • Cost-effective: For applications relying heavily on external APIs or databases, caching can reduce operational costs related to database and network calls.

3. Setting Up Caching in Spring Boot

To enable caching in Spring Boot, you need to add the necessary dependencies and configurations.

Add Caching Dependency

If you’re using Maven, add the following dependency:

xmlCopyEdit<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

For Gradle, use:

gradleCopyEditimplementation 'org.springframework.boot:spring-boot-starter-cache'

Enable Caching in Your Spring Boot Application

You need to enable caching in your Spring Boot application by adding the @EnableCaching annotation to one of your configuration classes.

javaCopyEdit@Configuration
@EnableCaching
public class CacheConfig {
}

This annotation enables Spring’s caching support across the application.


4. Understanding @Cacheable Annotation

The @Cacheable annotation tells Spring to cache the result of a method based on its arguments. If the method is called again with the same arguments, Spring will return the cached result rather than executing the method.

Example of @Cacheable

javaCopyEdit@Service
public class ProductService {

    @Cacheable(value = "products", key = "#id")
    public Product getProductById(Long id) {
        simulateSlowService();
        return new Product(id, "Product Name");
    }

    private void simulateSlowService() {
        try {
            Thread.sleep(3000); // Simulate a delay
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

In this example:

  • The @Cacheable annotation tells Spring to cache the result of getProductById.
  • The value parameter is the name of the cache.
  • The key parameter specifies the cache key, which in this case is the id of the product.

5. Caching Providers in Spring Boot

Spring Boot supports several caching providers, including:

  • Simple in-memory cache: Default caching provider (using ConcurrentMapCache).
  • EhCache: Popular open-source caching solution.
  • Redis: A fast, open-source key-value store.
  • Caffeine: High-performance, Java-based caching library.
  • Guava: Google’s caching library.

To use an external caching provider, you need to include the corresponding dependency and configure it in application.properties or application.yml.

Example: Using Redis for Caching

Add the Redis dependency:

xmlCopyEdit<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Configure Redis in application.properties:

propertiesCopyEditspring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

6. Cacheable Methods and Cache Names

In addition to basic method caching, Spring also allows you to specify cache names, expiration times, and conditional caching.

Cache Names

You can specify multiple cache names by providing an array for the value attribute:

javaCopyEdit@Cacheable(value = {"cache1", "cache2"}, key = "#id")
public Product getProductById(Long id) {
    // Method logic
}

This will store the cached data in both cache1 and cache2.

Conditional Caching

You can control when to cache results based on method parameters or other conditions:

javaCopyEdit@Cacheable(value = "products", key = "#id", condition = "#id > 10")
public Product getProductById(Long id) {
    // Method logic
}

Here, the cache will only be used if the id is greater than 10.


7. Cache Eviction and Expiration

Spring Boot supports cache eviction using the @CacheEvict annotation. This allows you to remove specific entries from the cache or clear the entire cache.

Example: Evicting Cache

javaCopyEdit@CacheEvict(value = "products", key = "#id")
public void deleteProduct(Long id) {
    productRepository.deleteById(id);
}

This will remove the cached entry for the product with the specified id when the deleteProduct method is called.

Cache Expiration

To set cache expiration times, you typically configure this at the provider level. For example, in Redis or EhCache, you can set TTL (Time To Live) settings to automatically expire cached entries after a certain period.


8. Advanced Caching Features (e.g., @CachePut, @CacheEvict)

@CachePut

The @CachePut annotation is used to update the cache without interfering with the method execution. It forces the cache to be updated with the method’s result even if the method is executed.

javaCopyEdit@CachePut(value = "products", key = "#product.id")
public Product updateProduct(Product product) {
    return productRepository.save(product);
}

Here, after saving the updated product, the cache is updated with the new value.

@CacheEvict (Advanced Use)

You can also evict the cache based on specific conditions like method execution or after a certain delay:

javaCopyEdit@CacheEvict(value = "products", allEntries = true)
public void clearCache() {
    // Logic to clear the cache
}

This clears all entries from the products cache.


9. Troubleshooting Caching Issues

  • Cache not updating: Ensure that the cache manager is properly configured, and check if the @CachePut and @CacheEvict annotations are being used correctly.
  • Inconsistent cache values: Verify that the cache key generation logic (key attribute in annotations) is accurate.
  • Cache misses: This may occur if the cache is being cleared unexpectedly or if the cache expires too quickly.

10. Summary

Caching in Spring Boot can greatly improve the performance of your applications by reducing redundant operations. By leveraging annotations like @Cacheable, @CachePut, and @CacheEvict, you can easily manage your cache logic. Spring Boot’s flexible caching framework supports a variety of cache providers, making it suitable for different types of applications, from small to large-scale systems.