Caffeine is a high-performance, near-optimal caching library for Java that integrates very well with Spring Boot. It provides features like size-based eviction, time-based expiration, refresh, and statistics.
Here’s a step-by-step guide with example:
1. Add Dependencies
In Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version> <!-- use latest -->
</dependency>
In Gradle:
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
2. Enable Caching in Spring Boot
Add @EnableCaching
in 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 CaffeineCacheApplication {
public static void main(String[] args) {
SpringApplication.run(CaffeineCacheApplication.class, args);
}
}
3. Configure Caffeine Cache
You can configure via application.yml:
spring:
cache:
cache-names: users
caffeine:
spec: maximumSize=1000,expireAfterWrite=5m
Or define a CaffeineCacheManager bean:
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;
import java.util.concurrent.TimeUnit;
@Configuration
public class CacheConfig {
@Bean
public Caffeine<Object, Object> caffeineConfig() {
return Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.maximumSize(1000);
}
@Bean
public CacheManager cacheManager(Caffeine<Object, Object> caffeine) {
CaffeineCacheManager cacheManager = new CaffeineCacheManager("users");
cacheManager.setCaffeine(caffeine);
return cacheManager;
}
}
4. Use Cache in a Service
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Cacheable("users")
public String getUserById(String userId) {
simulateSlowService(); // simulate DB call
return "User-" + userId;
}
private void simulateSlowService() {
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}
5. Test the Cache
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id) {
return userService.getUserById(id);
}
}
🔍 What happens:
- First request to
/user/123
→ takes ~3s (simulated DB call). - Next requests to
/user/123
→ return instantly (from cache). - After 5 minutes (or when cache size exceeds 1000 entries), the cache entry expires.