1️⃣
@Cacheable
Spring Cache의 가장 기본적이자 핵심적인 어노테이션이다. 캐시가 있으면 메서드를 실행하지 않고, 캐시가 없으면 메서드를 실행하고 결과를 캐시에 저장한다.
동작 방식
- 메서드 호출 시, 지정된 캐시(Key)가 이미 존재하는지 확인.
- 존재하면 DB나 외부 호출 없이 캐시의 결과를 바로 반환.
- 존재하지 않으면 메서드를 실행하고, 반환값을 캐시에 저장.
// "users" 캐시 저장소에 userId를 키로 사용
@Cacheable(value = "users", key = "#userId")
public User findUserById(Long userId) {
// 캐시에 없으면 이 로그가 찍히고 DB 조회가 발생한다.
log.info("Fetching user from DB: {}", userId);
return userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException());
}
*value: 사용할 캐시 저장소의 이름
**key: 캐시를 식별하는 키(SpEL 사용 가능)
언제 사용할까?
- 조회성(read-only) 데이터가 자주 호출될 때
- 변경 빈도가 낮은 데이터를 캐싱할 때 (예: 유저 프로필, 코드 목록, 상품 카테고리 등)
- 외부 API 호출 결과를 캐싱할 때
- 비용이 많이 드는 DB 조회(e.g., findById)
2️⃣
@CachePut
@Cacheable과 자주 혼동되지만 결정적인 차이가 있는데 @CachePut은 캐시를 확인하지 않고 메서드를 항상 실행하며 그 결과를 캐시에 덮어쓴다.
동작 방식
- 메서드를 항상 실행한다.
- 실행 결과를 캐시에 무조건 반영(업데이트) 한다.
- 메서드의 반환값을 그대로 반환한다.
// "users" 캐시 저장소의 #user.id 키에 해당하는 캐시를 갱신
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
// 이 메서드는 항상 실행되어 DB에 update 쿼리를 날린다.
log.info("Updating user in DB: {}", user.getId());
User updatedUser = userRepository.save(user); // DB 저장 (수정)
return updatedUser; // 반환된 updatedUser가 캐시에 저장됨
}
언제 사용할까?
- 작업 후 캐시를 갱신할 때 사용
- 기존 데이터를 DB에서 수정한 후, 캐시에 저장된 값도 최신 값으로 동기화해야 할 때 사용(예: 사용자 정보 수정, 게시글 수정 등)
3️⃣
@CacheEvict
@CacheEvict는 이름 그대로 캐시에 저장된 데이터를 제거(Evict)하는 역할을 한다. 캐시를 비워 다음 요청 시 다시 로드되도록 한다.
동작 방식
- 메서드 본체를 실행한다. (기본값)
- 메서드 실행이 성공적으로 완료되면, 지정된 key에 해당하는 캐시 항목을 삭제한다.
// "users" 캐시 저장소에서 userId 키에 해당하는 캐시 삭제
@CacheEvict(value = "users", key = "#userId")
public void deleteUser(Long userId) {
// 이 메서드는 항상 실행되어 DB에서 delete 쿼리를 날린다.
log.info("Deleting user from DB: {}", userId);
userRepository.deleteById(userId);
}
// "users" 캐시 저장소의 모든 데이터를 삭제
@CacheEvict(value = "users", allEntries = true)
public void refreshAllUsersCache() {
log.info("All user caches cleared.");
}
* allEntries = true: key와 상관없이 해당 value(캐시 저장소)의 모든 항목을 삭제한다. (e.g., 캐시 전체 초기화 시 유용)
언제 사용할까?
- DB에서 특정 데이터가 삭제되어 더 이상 캐시에 남아있으면 안 될 때.
- 관련된 데이터가 너무 많이 변경되어 캐시 전체를 리셋해야 할 때
🗓️ 표로 비교하기: @Cacheable vs @CachePut vs @CacheEvict
| 어노테이션 | 메서드 실행 여부 | 캐시 동작 | 주요 사용 시점 (CRUD) |
| @Cacheable | 캐시가 없을 때만 실행 | 캐시 조회 및 저장 | Read (조회) |
| @CachePut | 항상 실행 | 캐시 갱신 (덮어쓰기) | Update (수정) |
| @CacheEvict | 항상 실행 | 캐시 삭제 | Delete (삭제) |
'Programming > Spring' 카테고리의 다른 글
| [Spring] Batch작업이란? (0) | 2025.11.19 |
|---|---|
| [Spring] JWT의 구조 (0) | 2025.10.01 |
| [Spring] JPA에서 N+1이 발생하는 이유 (0) | 2025.09.24 |
| [Spring] Spring Framwork의 탄생 배경 (0) | 2025.07.16 |