본문으로 건너뛰기
Advertisement

2.6 캐싱 (Caching)

조회 비중이 큰 API·참조 데이터·통계는 캐시로 DB/외부 호출을 줄이면 응답 속도와 부하가 개선됩니다. 스프링은 선언적 캐싱(@Cacheable)과 CacheManager 추상화를 제공합니다.

작성 기준: Spring Boot 3.2.x, spring-boot-starter-cache

1. 의존성 및 캐시 활성화

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-cache'
}
@SpringBootApplication
@EnableCaching // 캐시 기능 활성화
public class Application { ... }

2. 로컬 캐시 (Caffeine) — 기본 추천

별도 서버 없이 인메모리 캐시가 필요할 때 Caffeine을 사용합니다.

implementation 'com.github.ben-manes.caffeine:caffeine'
spring:
cache:
type: caffeine
cache:
caffeine:
spec: maximumSize=500,expireAfterWrite=10m
  • maximumSize=500: 최대 500개 항목 유지
  • expireAfterWrite=10m: 쓰기 후 10분 뒤 만료

3. @Cacheable — 조회 결과 캐싱

메서드 반환값을 캐시에 넣고, 같은 인자로 다시 호출되면 캐시에서 반환합니다.

@Service
public class ProductService {

@Cacheable(value = "products", key = "#id")
public Product findById(Long id) {
return productRepository.findById(id).orElseThrow();
}

@Cacheable(value = "productList", key = "#categoryId + '-' + #page")
public List<Product> findByCategory(Long categoryId, Pageable page) {
return productRepository.findByCategoryId(categoryId, page);
}
}
  • value: 캐시 이름(네임스페이스)
  • key: 캐시 키. SpEL로 표현. 생략 시 인자 기반 기본 키 사용

4. @CacheEvict — 캐시 제거

데이터가 변경될 때 해당 캐시를 비워야 합니다.

@CacheEvict(value = "products", key = "#product.id")
public void update(Product product) {
productRepository.save(product);
}

@CacheEvict(value = "products", allEntries = true) // products 전체 비우기
public void deleteAllByCategory(Long categoryId) {
productRepository.deleteByCategoryId(categoryId);
}
  • allEntries = true: 해당 캐시 이름의 모든 항목 삭제

5. @CachePut — 캐시 갱신

메서드를 항상 실행하고, 반환값을 캐시에 넣거나 덮어씁니다. “저장 후 바로 캐시에 반영”할 때 사용합니다.

@CachePut(value = "products", key = "#result.id")
public Product save(Product product) {
return productRepository.save(product);
}

6. Redis 캐시 (분산 환경)

여러 서버가 같은 캐시를 공유할 때 Redis를 사용합니다.

implementation 'org.springframework.boot:spring-boot-starter-data-redis'
spring:
cache:
type: redis
data:
redis:
host: localhost
port: 6379
  • @Cacheable, @CacheEvict 등은 그대로 두고 CacheManager만 Redis로 바꾸면 됩니다.
  • TTL은 @Cacheable(cacheNames = "products", ...)에 대응하는 Redis 설정 또는 RedisCacheConfiguration으로 지정합니다.

7. 조건부 캐싱 (condition, unless)

  • condition: SpEL이 true일 때만 캐시 조회/저장
  • unless: SpEL이 true이면 캐시에 저장하지 않음
@Cacheable(value = "users", key = "#id", unless = "#result == null")
public User findById(Long id) { ... }

캐시 키가 단순하면 key 생략 가능. 복잡한 키나 null 제외는 condition/ unless로 제어하면 됩니다. Redis 사용 시 만료 시간·메모리 정책을 운영 환경에 맞게 꼭 설정하세요.

Advertisement