Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Declarative Caching in Spring Boot with Spring Cache and Redis

Tech 1

Dependency Configuration

To integrate Spring Cache with a Redis backend, include the following dependencies in your Maven configuration. Spring Boot automatically selects the cache implementation based on the available libraries on the classpath.

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

Activating Caching

Enable the caching functionality by adding the @EnableCaching annotation to the main application class. This instructs Spring to look for cache-related annotations and create the necessary proxy objects.

@SpringBootApplication
@EnableCaching
public class InventoryManagementApplication {
    public static void main(String[] args) {
        SpringApplication.run(InventoryManagementApplication.class, args);
    }
}

Core Cache Annotations and Usage

Spring Cache operates via AOP (Aspect-Oriented Programming). A proxy intercepts method calls to handle cache logic before or after the actual method execution. If a method is marked with @Transactional and the transaction rolls back, cache operations will typically be suppressed to maintain consistency.

Synchronizing Cache with Data Updates

The @CachePut annotation updates the cache with the methods' return value. By default, Redis key are structured as cacheName::keyValue.

@CachePut(cacheNames = "productCache", key = "#product.id")
@PostMapping("/products")
public Product createProduct(@RequestBody Product product) {
    productRepository.save(product);
    return product;
}

// Alternative SpEL expressions for the key:
// key = "#result.id" (property of the return object)
// key = "#p0.id" (property of the first argument)
// key = "#root.args[0].id" (explicit argument index)

Conditional Cache Retrieval

@Cacheable checks if the data exists in the cache first. If found, the method body is skipped, and the cached value is returned. If not found, the method executes, and the result is stored in the cache.

@GetMapping("/products/{id}")
@Cacheable(cacheNames = "productCache", key = "#id")
public Product fetchProductById(@PathVariable Long id) {
    // This code only executes if there is a cache miss
    return productRepository.findById(id);
}

Cache Invalidation

@CacheEvict is used to remove entries from the cache, ensuring stale data is not served after a deletion or a bulk update.

// Removes a specific entry based on the ID
@DeleteMapping("/products/{id}")
@CacheEvict(cacheNames = "productCache", key = "#id")
public void removeProduct(@PathVariable Long id) {
    productRepository.deleteById(id);
}

// Removes all entries under the specified cache namespace
@DeleteMapping("/products/clear")
@CacheEvict(cacheNames = "productCache", allEntries = true)
public void clearProductCatalog() {
    productRepository.deleteAll();
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.