WeeklyPaper: Spring Cache에서 @Cacheable, @CachePut, @CacheEvict의 차이점과 각각을 어떤 상황에서 사용하는 것이 적절한지 설명해주세요.
스프링에서는 스프링 AOP 기반으로 캐시가 장독하여 어노테이션으로 AOP를 설정할 수 있어서 간편하게 사용할 수 있다. 주로 사용되는 어노테이션은 @Cacheable, @CachePut, @CacheEvict다.
build.gradle에 추가하자:
implementation 'org.springframework.boot:spring-boot-starter-cache'
@Cacheable
캐시 생성과 전달을 담당한다.
메서드가 호출 될때마다 이 메서드는 이미 호출이 되었는지 확인하기 위해 캐시가 확인된다.
- 캐시에 데이터가 없을 경우, 기존의 로직을 실행 후 캐시에 데이터를 추가한다.
- 캐시에 데이터가 있을 경우, 메서드는 호출되지 않고 캐시의 데이터만 반환한다.
// 캐시 저장
@Cacheable("userCacheStore")
public User cacheable(String date) {
System.out.println("cacheable 실행");
return User;
}
// 캐시 저장 (key를 지정한 경우)
@Cacheable(value="userCacheStore", key = "#user.name")
public User cacheableByKey(User user) {
System.out.println("cacheable 실행");
return User;
}
//조건부 캐시 실행 (with condition)
@Cacheable(value = "userCacheStore", key = "#user.name", condition = "#user.name.length() > 5")
public User cacheableByKey(User user) {
System.out.println("cacheableWithCondition 실행");
return User;
}
- @Cacheable("userCacheStore")
- key없이 캐시 저장
- 처음으로 메서드가 호출될 경우, "cacheable 실행" 문자열이 출력되고 반환값인 User은 개시 저장소에 저장된다.
- 그 다음 모든 메서드 호출은 캐시 저장소에 저장된 User 값이 반환되고, 문자열은 출력되지 않는다.
- @Cacheable(value="userCacheStore", key = "#user.name")
- key를 사용해서 캐시 저장
- 처음으로 특정 name값을 가진 유저가 들어올때는 "cachable 실행" 문자열이 출력되고 그 이름을 가진 유저 객체 데이터는 캐싱된다.
- 같은 이름을 가진 유저 객체로 다시 메서드를 호출하면 캐싱된 유저 데이터 객체다 반환되고, "cachable 실행" 문자열은 출력되지 않는다.
- @Cacheable(value = "userCacheStore", key = "#user.name", condition = "#user.name.length() > 5")
- 조건부 캐싱 - @Cachable 어노테이션에 condition 속성을 추가해서 사용 가능하다.
@CachePut
캐시 수정 내용을 담당한다. @Cacheable과 유사하게 실행 결과를 캐시에 저장하지만, 조회 시 저장된 캐시 내용을 사용하지 하노고 항상 메서드를 실행한다.
@CachePut(value="userCacheStore", key="#user.name")
public User cachePut(User user) {
System.out.println("cachePut 실행");
return User;
}
- 메서드 실행에 영향을 주지 않고 캐시를 갱신해야되는 경우에만 사용된다.
- @Cacheable와 같은 option들을 사용하면 된다.
@CacheEvict
캐시 삭제를 담당한다.
// 캐시 제거
@CacheEvict("userCacheStore")
public User cacheEvict(String date) {
System.out.println("cacheEvict 실행");
...
return User;
}
// name 키 값을 가진 캐시만 제거
@CacheEvict("userCacheStore", key="#user.name")
public User cacheEvictByKey(User user) {
System.out.println("cacheEvictByKey 실행");
...
return User;
}
// 캐시에 저장된 값을 모두 제거
@CacheEvict("userCacheStore", allEntries = true)
public User cacheEvictAllEntries() {
System.out.println("cacheEvictAllEntries 실행");
...
return User;
}
@CacheEvict(value="userCacheStore", beforeInvocation = true)
public User cacheEvictBeforeInvocation() {
System.out.println("cacheEvictBeforeInvocation 실행");
...
return User;
}
- @CacheEvict("userCacheStore") - 기본
- userCacheStore라는 이름의 캐시에서 특정 항목 하나만 제거한다. 어떤 항목을 지울지는 메서드의 매개변수를 기반으로 결정된다.
- cacheEvict(String date) 메서드가 호출될 때, 만약 date 값이 "2025-10-20"이라면, "userCacheStore" 캐시에서 "2025-10-20"이라는 키(key)를 가진 항목을 찾아 삭제한다.
- @CacheEvict("userCacheStore", key="#user.name")
- 매개변수의 이름이 키로 사용되는 객체 데이터가 캐시 안에 저장되어있다면 삭제된다.
- @CacheEvict("userCacheStore", allEntries = true)
- 모든 항목을 한 번에 제거한다. (그냥 캐시 전체를 비운다)
- @CacheEvict(value="userCacheStore", beforeInvocation = true)
- 메서드 로직이 실행되기 전에 혹은 후에 캐시를 삭제할지 결정한다
- 예) beforeInvocation = true 옵션은 메서드 로직이 실행되기 전에 캐시를 먼저 삭제한다.
- 기본값은 false이며, 이때는 메서드가 성공적으로 완료된 후에 캐시를 삭제한다. (즉, 메서드 실행 중 예외가 발생하면 캐시가 삭제되지 않는다.)
- 메서드 로직이 실행되기 전에 혹은 후에 캐시를 삭제할지 결정한다
자료
'Spring' 카테고리의 다른 글
| [Spring TDD] Mockito의 Mock, Stub, Spy (1) | 2025.08.18 |
|---|---|
| [JPA] 트랜잭션의 ACID 속성 중 격리성(Isolation)이 보장되지 않을 때 (0) | 2025.07.23 |
| [JPA] N+1 문제 (4) | 2025.07.21 |
| [SpringBoot] @Controller와 @RestController의 차이점과 요청 처리 흐름 (0) | 2025.07.03 |
| [Spring] Spring AOP 개념과 실제 활용 사례 (0) | 2025.07.01 |