CacheManager

PUROMANGA·2025년 5월 20일

기술스택

목록 보기
1/22

CacheManager

CacheManager는 캐시를 관리해주는 매니저이다.

일반적으로 스프링에서 캐시를 관리해주는 매니저는 두 가지가 있다.

SimpleCacheManager, ConcurrentMapCacheManager

구현 방법

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("user", "product");
    }
}

@EnableCaching 붙이면 스프링은 자동으로 CacheManager 빈을 찾아서 사용하게 된다.

@Bean으로 직접 지정하면 그 쪽이 우선시되게 된다.

Redis도 추가해보자!

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

이러한 의존성을 추가해줌으로서 스프링 내부에서 CacheManager을 사용할 수 있게 된다.

컴포넌트설명
RedisTemplateRedis에 직접 명령어 날릴 수 있는 템플릿
RedisCacheManager@Cacheable과 함께 사용하는 캐시 매니저
RedisConnectionFactory실제 Redis 연결을 만들어주는 팩토리
RedisSerializerJSON, JDK 직렬화 등 Value 변환기
Lettuce기본 Redis 클라이언트 (비동기, 넌블로킹)

이것은 우리가 직접 구현해야할 것이다.

@Cacheable / @CachePut / @CacheEvict
        ↓
   CacheManager (인터페이스)
        ↓
  ├─ SimpleCacheManager      → JVM 캐시
  ├─ ConcurrentMapCacheManager → 쓰레드 세이프 JVM 캐시
  └─ RedisCacheManager       ✅ Redis 연동용 캐시 매니저

흐름

@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
    return userRepository.findById(id).orElseThrow();
}

이렇게 찾은 db의 조회 결과를 캐시에 저장하게 되는데 이 코드 실행시 Spring 내부 동작은 다음과 같다.

1. @Cacheable(value = "user")

→ “user라는 이름의 캐시 공간(Cache)을 써야겠군!”

2. Spring은 CacheManager에게 "user"라는 이름의 캐시 인스턴스를 요청함.

cacheManager.getCache("user")

3. 이때 사용하는 cacheManager는 어디서 오냐?

@Configuration에서 너가 @Bean으로 등록한 CacheManager

4. 예시

@Bean
public CacheManager cacheManager() {
    return new RedisCacheManager(...);  // 또는 ConcurrentMapCacheManager
}

5. 저장

RedisCacheManager라면 → Redis에 "user::id" 형태로 저장
ConcurrentMapCacheManager라면 → JVM 메모리에 "user::id"로 저장

오류

만약에 너가 RedisCacheManager랑 ConcurrentMapCacheManager 둘 다 bean등록하게 되면 오류가 생길 수 있어.

따라서

@Primary

@Bean
@Primary
public CacheManager redisCacheManager() {
    return RedisCacheManager.builder(...).build();
}

cacheManager 속성 직접 명시

@Cacheable(cacheManager = "concurrentMapCacheManager", value = "user", key = "#id")
public User getFromJvm(Long id) { ... }

@Cacheable(cacheManager = "redisCacheManager", value = "user", key = "#id")
public User getFromRedis(Long id) { ... }

하는 걸로 어떤 캐시 매니저를 사용할지 직접적으로 명시해줄 수 있지.

0개의 댓글