Programming/Spring

[Spring]@Cacheable, @CachePut, @CacheEvict

_채채_ 2025. 10. 20. 09:31

1️⃣

@Cacheable

Spring Cache의 가장 기본적이자 핵심적인 어노테이션이다. 캐시가 있으면 메서드를 실행하지 않고, 캐시가 없으면 메서드를 실행하고 결과를 캐시에 저장한다.

 

동작 방식

  1. 메서드 호출 시, 지정된 캐시(Key)가 이미 존재하는지 확인.
  2. 존재하면 DB나 외부 호출 없이 캐시의 결과를 바로 반환.
  3. 존재하지 않으면 메서드를 실행하고, 반환값을 캐시에 저장.
// "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은 캐시를 확인하지 않고 메서드를 항상 실행하며 그 결과를 캐시에 덮어쓴다.

 

동작 방식

  1. 메서드를 항상 실행한다.
  2. 실행 결과를 캐시에 무조건 반영(업데이트) 한다.
  3. 메서드의 반환값을 그대로 반환한다.
// "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)하는 역할을 한다. 캐시를 비워 다음 요청 시 다시 로드되도록 한다.

 

동작 방식

 

  1. 메서드 본체를 실행한다. (기본값)
  2. 메서드 실행이 성공적으로 완료되면, 지정된 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