Sunday, January 19, 2025
HomeProgrammingWhat Is Spring Boot Caching?

What Is Spring Boot Caching?

Spring Boot Caching

Caching is an optimization technique that stores copies of frequently accessed data in memory or another fast-access storage. In Spring Boot, caching can greatly enhance the performance of an application by reducing redundant calculations and improving response times. Spring Boot provides a comprehensive, flexible caching abstraction that allows you to easily integrate different caching mechanisms into your application.

Here’s an overview of how caching works in Spring Boot, and how to implement it effectively.

1. Enable Caching in Spring Boot

To enable caching in a Spring Boot application, you need to:

  1. Add the @EnableCaching annotation to your main application class or any configuration class.
  2. Configure a cache manager to manage caching operations. Spring Boot supports several caching providers (e.g., ConcurrentMap, EhCache, Redis, Caffeine, etc.).

Example: Enabling Caching

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching // Enable caching in Spring Boot
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2. Caching Annotations

Spring provides several annotations to control the caching behavior:

  • @Cacheable: Caches the result of a method.
  • @CachePut: Updates the cache with the result of a method execution.
  • @CacheEvict: Removes entries from the cache.
  • @Caching: Combines multiple cache operations (e.g., evicting and putting) on a method.

2.1 @Cacheable

The @Cacheable annotation is used to cache the result of a method. It checks whether the result for a method call is already present in the cache. If the result is present, the method is not executed, and the cached value is returned. If the result is not present, the method is executed and the result is cached.

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    @Cacheable("products")
    public Product getProductById(Long productId) {
        // Simulate a slow database call
        simulateSlowService();
        return new Product(productId, "Sample Product");
    }

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

In this example:

  • If getProductById(1L) is called multiple times, the result is cached after the first call and returned from the cache in subsequent calls.
See also  Java String Length Method with Examples

2.2 @CachePut

The @CachePut annotation is used when you want to update the cache regardless of whether the method was called or not. This is useful when you want to refresh the cache with new values.

import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    @CachePut(value = "products", key = "#product.id")
    public Product updateProduct(Product product) {
        // Save product to the database
        return product; // Simulate the update operation
    }
}

Here, every time updateProduct is called, the cache will be updated with the new value of the product.

2.3 @CacheEvict

The @CacheEvict annotation removes an entry from the cache. You can use it to remove items when they are updated or deleted.

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    @CacheEvict(value = "products", key = "#productId")
    public void deleteProduct(Long productId) {
        // Delete product from the database
    }
}

In this example, calling deleteProduct will remove the cached product with the specified productId.

2.4 @Caching

The @Caching annotation allows you to apply multiple caching operations in one place. You can combine @Cacheable, @CacheEvict, and @CachePut.

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    @Caching(
        put = @CachePut(value = "products", key = "#product.id"),
        evict = @CacheEvict(value = "products", key = "#product.id")
    )
    public Product saveProduct(Product product) {
        // Save the product and evict existing cache
        return product;
    }
}

3. Configuring a Cache Manager

Spring Boot provides default support for caching using ConcurrentMap, but you can customize the cache provider by adding relevant dependencies and configuration.

See also  Introduction to Java

3.1 In-Memory Caching (ConcurrentMap)

Spring Boot can use ConcurrentMapCacheManager by default, which stores the cache in memory.

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("products"); // Cache name is "products"
    }
}

3.2 Using Redis for Caching

You can integrate Redis as a distributed caching provider by adding the Redis dependency to your pom.xml or build.gradle:

<!-- Add Redis dependencies -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Configure Redis as the cache manager:

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.redis.RedisCacheManager;
import org.springframework.cache.redis.RedisCacheConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@EnableCaching
public class RedisCacheConfig {

    @Bean
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig();
        return RedisCacheManager.builder(redisTemplate).cacheDefaults(cacheConfig).build();
    }
}

3.3 Using Caffeine for Caching

Caffeine is an in-memory caching library that offers higher performance compared to simple ConcurrentMap cache. To use it, add the following dependency:

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

Then configure it in your application.properties or application.yml file.

spring.cache.type=caffeine
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

Alternatively, you can configure it manually:

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CaffeineCacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder().maximumSize(100).expireAfterAccess(10, TimeUnit.MINUTES));
        return cacheManager;
    }
}

4. Cache Names and Key Generation

  • Cache Names: A cache name is required to identify the cache. It’s specified in annotations like @Cacheable("cacheName"). Each cache manager can have multiple caches, each identified by its name.
  • Cache Key: By default, Spring Boot uses the method parameters as the cache key. You can customize the cache key using the key attribute in annotations like @Cacheable(key = "#id").

5. Cache Configuration in application.properties

Spring Boot allows you to configure caching properties directly in the application.properties or application.yml file:

spring.cache.type=redis          # Redis as the cache manager
spring.cache.redis.time-to-live=600000  # Cache expiration time in milliseconds
spring.cache.caffeine.spec=maximumSize=500,expireAfterWrite=10m

Conclusion

Spring Boot’s caching support simplifies the integration of caching in your application. By leveraging annotations like @Cacheable, @CachePut, and @CacheEvict, and selecting the right caching provider (e.g., Redis, Caffeine, EhCache), you can drastically improve the performance and scalability of your applications.

See also  How can I extract the file name from a path, regardless of the OS or path format?

Make sure to choose the cache manager based on your application’s needs, such as using an in-memory cache for small-scale applications or distributed caching systems like Redis for large-scale, multi-instance applications.

RELATED ARTICLES
0 0 votes
Article Rating

Leave a Reply

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
- Advertisment -

Most Popular

Recent Comments

0
Would love your thoughts, please comment.x
()
x