Spring Boot @Cacheable Annotation

🚀 Introduction: Why Use @Cacheable in Spring Boot?

When an application frequently queries a database, it can lead to performance bottlenecks. Spring Boot provides a built-in caching mechanism using the @Cacheable annotation to:

Reduce redundant database calls
Improve application response time
Store frequently accessed data in memory

In this guide, you will learn how to:
✔ Use @Cacheable to enable caching in Spring Boot
✔ Configure different cache providers (SimpleCache, Redis)
✔ Understand @CacheEvict and @CachePut for cache management

1️⃣ Enabling Caching in Spring Boot

Before using @Cacheable, enable caching in your Spring Boot application using @EnableCaching.

@Configuration
@EnableCaching
public class CacheConfig {
}

This enables Spring's annotation-driven caching mechanism.

2️⃣ Using @Cacheable to Cache Method Results

The @Cacheable annotation stores method return values in a cache so that the next time the method is called with the same parameters, it fetches the result from the cache instead of executing the method.

✅ Example: Basic @Cacheable Usage

@Service
public class UserService {

    @Cacheable("users")
    public User getUserById(Long id) {
        System.out.println("Fetching user from database...");
        return new User(id, "John Doe");
    }
}

First-time calls will query the database. Subsequent calls with the same id fetch data from cache.

3️⃣ Configuring a Cache Provider in Spring Boot

Spring Boot supports multiple cache providers, including:

  • SimpleCache (Default, in-memory cache)
  • Redis (Recommended for distributed caching)
  • EhCache
  • Caffeine
  • Hazelcast

3.1 Using the Default In-Memory Cache (No Configuration Required)

By default, Spring Boot uses SimpleCache, an in-memory cache that doesn’t persist across restarts.

No additional configuration is needed. Just enable @EnableCaching.

3.2 Using Redis as a Cache Provider

For production applications, it’s better to use Redis for distributed caching.

✅ Step 1: Add Redis Dependencies in pom.xml

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

✅ Step 2: Configure Redis in application.properties

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

✅ Step 3: Define a RedisCacheManager

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public RedisCacheConfiguration cacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10)) // Set TTL for cache entries
                .disableCachingNullValues();
    }
}

Now, the @Cacheable annotation will store results in Redis instead of in-memory.

4️⃣ @Cacheable Key and Condition Parameters

You can customize @Cacheable behavior using parameters like key and condition.

4.1 Using key to Customize Cache Keys

By default, @Cacheable caches data using method parameters as the key. You can specify a custom key using Spring Expression Language (SpEL).

@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) { ... }

Caches users with id as the key.

4.2 Using condition to Control Caching

Use condition to cache only specific data.

@Cacheable(value = "users", condition = "#id > 10")
public User getUserById(Long id) { ... }

Caches results only for id > 10.

5️⃣ Removing Cached Data with @CacheEvict

When data changes, you need to remove outdated cache entries. Use @CacheEvict to clear specific caches.

@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
    System.out.println("User deleted from database.");
}

Removes the cached user entry for the given id.

5.1 Clearing the Entire Cache

@CacheEvict(value = "users", allEntries = true)
public void deleteAllUsers() {
    System.out.println("All users deleted from cache.");
}

Removes all entries in the users cache.

6️⃣ Updating Cache Entries with @CachePut

Use @CachePut when you want to update the cache with new data after a method executes.

@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
    System.out.println("Updating user in database...");
    return user;
}

Updates the cache with new user data.

7️⃣ Combining @Cacheable, @CacheEvict, and @CachePut

Annotation Purpose
@Cacheable Caches the method result.
@CacheEvict Removes a specific entry or clears all cache.
@CachePut Updates cache with the latest method return value.

✅ Example: Complete Caching Service

@Service
public class UserService {

    @Cacheable("users")
    public User getUserById(Long id) {
        System.out.println("Fetching user from database...");
        return new User(id, "John Doe");
    }

    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        System.out.println("User deleted from database.");
    }

    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        System.out.println("Updating user in database...");
        return user;
    }
}

Ensures efficient caching with proper invalidation and updates.

🎯 Conclusion: Why Use @Cacheable in Spring Boot?

By using @Cacheable, you can:
Improve application performance by reducing database calls.
Use in-memory or external cache (like Redis) for efficiency.
Properly manage cache with @CacheEvict and @CachePut.

🚀 Which caching provider do you prefer: Redis or SimpleCache? Comment below!

🔗 Bookmark this guide for future reference! 🚀

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare