Spring Cache를 활용한 캐싱
Spring의 `@Cacheable` 및 관련 주석을 사용해 캐싱 메커니즘을 구현하고 응답 시간을 개선합니다.
Spring Cache를 활용한 캐싱은(는) CoddyKit의 무료 Spring Boot 4 Complete Guide 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Spring Boot 4 Complete Guide 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Spring Boot 4 Complete Guide 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Boost Performance with Caching!
Imagine your app constantly fetching the same data from a slow database. This can make it sluggish! Caching is like having a super-fast shortcut for frequently accessed data.
Instead of going to the database every time, the app stores a copy of the data in a temporary, quick-access location (the cache). When the data is requested again, it checks the cache first.
- Faster Responses: Users get data quicker.
- Reduced Load: Less strain on your database or external services.
Spring Cache: Simplicity & Power
Spring Framework provides an amazing abstraction for caching. It simplifies integrating caching into your applications, so you don't have to write complex caching logic yourself.
With Spring Cache, you can use simple annotations to apply caching behavior to your methods. It supports various underlying cache providers like EhCache, Redis, or Caffeine, letting you swap them out easily without changing your code.
Getting Started: Add Dependencies
To use Spring's caching abstraction, you need to add the spring-boot-starter-cache dependency. This starter brings in Spring's caching infrastructure and a simple in-memory cache manager by default.
For a more robust in-memory cache, we'll also add Caffeine, a high-performance Java caching library.
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>Enable Caching & @Cacheable
First, you need to enable caching in your Spring Boot application by adding the @EnableCaching annotation to your main application class or a configuration class.
Then, the @Cacheable annotation is used on a method to indicate that its result should be cached. The first time the method is called, its result is stored. Subsequent calls with the same arguments will return the cached result without executing the method.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching // Enable caching for the app
public class CachingApp {
public static void main(String[] args) {
SpringApplication.run(CachingApp.class, args);
}
}@Cacheable in Action: Service Layer
Let's see @Cacheable on a service method. Notice the cacheNames attribute, which specifies the name of the cache where results will be stored (e.g., "products").
When getProductById is called, Spring checks the "products" cache. If a product with that ID is found, it's returned. Otherwise, the method executes (simulating a database call), and its result is cached.
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
// Imagine this is a simple data class
class Product {
private Long id;
private String name;
public Product(Long id, String name) {
this.id = id; this.name = name;
}
public Long getId() { return id; }
public String getName() { return name; }
@Override
public String toString() {
return "Product{" + id + ", " + name + "}";
}
}
@Service
public class ProductService {
@Cacheable(cacheNames = "products")
public Product getProductById(Long id) {
System.out.println(
"Fetching product " + id + " from DB...");
// Simulate a slow database call
try { Thread.sleep(1000); }
catch (InterruptedException e) {}
return new Product(id, "Product-" + id);
}
}
// Main Application (from previous scene)
// Add a runner to demonstrate
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableCaching
public class CachingApp {
public static void main(String[] args) {
SpringApplication.run(CachingApp.class, args);
}
@Bean
public CommandLineRunner run(ProductService service) {
return args -> {
System.out.println("First call:");
System.out.println(service.getProductById(1L));
System.out.println("Second call (cached):");
System.out.println(service.getProductById(1L));
System.out.println("Third call (new ID):");
System.out.println(service.getProductById(2L));
};
}
}Keep Your Cache Fresh with @CachePut
What if you update a product? The old version might still be in the cache! The @CachePut annotation is used to update the cache with the result of a method execution.
Unlike @Cacheable, @CachePut always executes the method and then places the result into the cache. This is perfect for update operations where you want the cache to reflect the latest data.
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
// Product and CachingApp classes as before
@Service
public class ProductService {
// ... getProductById as before ...
@CachePut(cacheNames = "products", key = "#product.id")
public Product updateProduct(Product product) {
System.out.println(
"Updating product " + product.getId() + " in DB...");
// Simulate DB update
try { Thread.sleep(500); }
catch (InterruptedException e) {}
return product; // Return updated product
}
}
// Main Application
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class CachingApp {
public static void main(String[] args) {
SpringApplication.run(CachingApp.class, args);
}
@Bean
public CommandLineRunner run(ProductService service) {
return args -> {
System.out.println("--- @CachePut Demo ---");
Product p1 = service.getProductById(1L); // Cached
System.out.println("Fetched: " + p1);
Product updatedP1 = new Product(1L, "Updated Product 1");
service.updateProduct(updatedP1); // Updates cache
System.out.println("Updated: " + updatedP1);
Product p1AfterUpdate = service.getProductById(1L); // Fetches from updated cache
System.out.println("After update: " + p1AfterUpdate);
};
}
}
// Product class (same as before)
class Product {
private Long id;
private String name;
public Product(Long id, String name) {
this.id = id; this.name = name;
}
public Long getId() { return id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override
public String toString() {
return "Product{" + id + ", '" + name + "'}";
}
}Clearing Cache with @CacheEvict
When an item is deleted, you want to remove it from the cache so that no stale data is accidentally served. The @CacheEvict annotation is used for this.
allEntries = true: Clears all entries in the specified cache (e.g., "products").- Without
allEntries = true: Clears a specific entry based on the method's arguments (e.g., a specific product ID).
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
// Product and CachingApp classes as before
@Service
public class ProductService {
// ... getProductById and updateProduct as before ...
@CacheEvict(cacheNames = "products", key = "#id")
public void deleteProduct(Long id) {
System.out.println(
"Deleting product " + id + " from DB...");
// Simulate DB delete
try { Thread.sleep(500); }
catch (InterruptedException e) {}
}
@CacheEvict(cacheNames = "products", allEntries = true)
public void clearAllProductsCache() {
System.out.println("Clearing all products from cache...");
}
}
// Main Application
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class CachingApp {
public static void main(String[] args) {
SpringApplication.run(CachingApp.class, args);
}
@Bean
public CommandLineRunner run(ProductService service) {
return args -> {
System.out.println("--- @CacheEvict Demo ---");
service.getProductById(1L); // Cache product 1
service.getProductById(2L); // Cache product 2
System.out.println("Before delete: " +
service.getProductById(1L));
service.deleteProduct(1L); // Evict product 1
System.out.println("After delete, calling product 1 again:");
service.getProductById(1L); // Will hit DB again
System.out.println("Clearing all cache entries...");
service.clearAllProductsCache();
System.out.println("Calling product 2 after full clear:");
service.getProductById(2L); // Will hit DB again
};
}
}
// Product class (same as before)
class Product {
private Long id;
private String name;
public Product(Long id, String name) {
this.id = id; this.name = name;
}
public Long getId() { return id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override
public String toString() {
return "Product{" + id + ", '" + name + "'}";
}
}Naming Caches & Custom Keys
Each caching annotation requires one or more cacheNames (or value) to specify which cache to use. Spring automatically generates cache keys based on method parameters by default.
However, you can customize the key using the key attribute, which accepts Spring Expression Language (SpEL). This gives you fine-grained control over how cached entries are identified.
key = "#id": Uses theidparameter as the cache key.key = "#product.id": Uses theidproperty of theproductobject.
Configuring a Cache Manager (Caffeine)
Spring Boot uses a simple in-memory cache manager by default. For more advanced features like time-based eviction or maximum size, you can configure a specific CacheManager.
Here's how to configure Caffeine, a popular high-performance in-memory cache, by creating a CaffeineCacheManager bean. We define a cache named "products" with a maximum size and expiration after write.
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 CacheManager cacheManager() {
CaffeineCacheManager cacheManager =
new CaffeineCacheManager("products");
cacheManager.setCaffeine(caffeineBuilder());
return cacheManager;
}
Caffeine<Object, Object> caffeineBuilder() {
return Caffeine.newBuilder()
.initialCapacity(100)
.maximumSize(500)
.expireAfterWrite(10, TimeUnit.MINUTES)
.recordStats();
}
}Quick Check: Cache Annotations
You've learned about the core caching annotations in Spring. Let's test your understanding.
Caching Power-Up: Recap
You've successfully learned how to implement caching in your Spring Boot application to dramatically improve performance!
- Use
@EnableCachingto activate caching. @Cacheablecaches method results for faster reads.@CachePutupdates cache entries after method execution.@CacheEvictremoves entries from the cache.- Specify
cacheNamesand use SpEL for customkeygeneration. - Configure a custom
CacheManager(like Caffeine) for advanced control.
By intelligently using these annotations, you can reduce database load and provide a snappier experience for your users.
자주 묻는 질문
“Spring Cache를 활용한 캐싱” 강의는 무료인가요?
네 — “Spring Cache를 활용한 캐싱” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Spring Boot 4 Complete Guide 강의 전체를 잠금 해제할 수 있습니다. Spring Boot 4 Complete Guide 강의에는 총 4개의 강의가 포함되어 있습니다.
“Spring Cache를 활용한 캐싱”에서 뭘 배우나요?
Spring의 `@Cacheable` 및 관련 주석을 사용해 캐싱 메커니즘을 구현하고 응답 시간을 개선합니다. 브라우저에서 직접 실행하는 실습 코드로 Spring Boot 4 Complete Guide을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Spring Boot 4 Complete Guide을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Spring Boot 4 Complete Guide은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“Spring Cache를 활용한 캐싱” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Spring Boot 4 Complete Guide 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Spring Boot 4 Complete Guide 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 사용자 정의 Spring Data 저장소
- NoSQL 데이터베이스 통합
- Spring Cache를 활용한 캐싱
- Flyway를 활용한 데이터베이스 마이그레이션