Advanced Caching Techniques in Spring

Caching is an essential technique for improving application performance by storing frequently accessed data. Spring Framework offers a robust caching abstraction that simplifies cache management. In this post, we'll explore advanced caching techniques in Spring, including cacheable methods, cache eviction, and cache management.

1. Setting Up Caching in Spring

To get started, ensure you have the following dependencies in your pom.xml (for Maven users):

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>

Enable caching in your Spring Boot application by adding the @EnableCaching annotation to your main application class:


import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class CachingApplication { public static void main(String[] args) { SpringApplication.run(CachingApplication.class, args); } }

2. Using @Cacheable Annotation

The @Cacheable annotation indicates that the result of a method call should be cached. Here’s an example:


import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class UserService { @Cacheable("users") public User getUserById(Long id) { // Simulate a slow service call simulateSlowService(); return findUserById(id); } private void simulateSlowService() { try { Thread.sleep(3000); // Simulate delay } catch (InterruptedException e) { throw new RuntimeException(e); } } private User findUserById(Long id) { // Fetch user from database return new User(id, "User " + id); } }

In the example above, the first time getUserById is called with a specific ID, the result will be cached. Subsequent calls with the same ID will return the cached result instantly.

3. Configuring Cache Manager

You can configure a cache manager in your Spring configuration. Here’s an example using an in-memory cache (Caffeine):


import com.github.benmanes.caffeine.cache.Caffeine; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.TimeUnit; @Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { return new CaffeineCacheManager("users", Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(100)); } }

4. Evicting Cached Data with @CacheEvict

You can remove cached data using the @CacheEvict annotation. Here’s how you can use it:


import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; @Service public class UserService { @CacheEvict(value = "users", key = "#id") public void updateUser(Long id, User user) { // Update user logic } }

In the example above, the cache for the user with the given ID is evicted whenever the updateUser method is called.

5. Using @CachePut to Update Cache

If you want to update the cache without evicting it, use the @CachePut annotation:


import org.springframework.cache.annotation.CachePut; import org.springframework.stereotype.Service; @Service public class UserService { @CachePut(value = "users", key = "#user.id") public User updateUser(User user) { // Update the user in the database return user; } }

6. Viewing Cached Data

To view the cached data, you can create a method to retrieve it from the cache:


import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; @Service public class CacheService { private final CacheManager cacheManager; public CacheService(CacheManager cacheManager) { this.cacheManager = cacheManager; } public User getCachedUser(Long id) { Cache cache = cacheManager.getCache("users"); return cache.get(id, User.class); } }


Comments

Popular posts from this blog

How to Run Python Script in PM2 Server

Handling Performance Bottlenecks in Spring Applications

Retry in SprinBoot Application