스프링 프레임워크

springboot에 CacheResolver로 MultipleCacheManager 구성하기

blogger903 2024. 6. 18. 16:18
728x90

이번 포스트는 springboot로 로컬캐시로 ehCache를 구성한 상태에서 글로벌캐시로 redis를 구성하려고 합니다

 

환경

  • springboot 3.1.10
  • gradle 8.7
  • java 17

현재 로컬캐시로 ehCache 의존성을 추가해 cacheManager를 단독으로 사용중입니다.

 

cacheManager를 여러개 등록하고 CacheResolver를 통해 cacheManager를 Resolve 하겠습니다.

 

CachingConfigurerSupport를 상속하는 구조로 구성했으나 Spring Framework 6 버전부터 Deprecated 되었습니다

@EnableCaching
@Configuration
public class MultipleCacheManagerConfig extends CachingConfigurerSupport {

    private final CacheManager ehCacheManager;
    private final CacheManager redissonCacheManager;

    public MultipleCacheManagerConfig(@Qualifier("ehCacheManager") CacheManager ehCacheManager,
                               @Qualifier("redissonCacheManager") CacheManager redissonCacheManager) {
        this.ehCacheManager = ehCacheManager;
        this.redissonCacheManager = redissonCacheManager;
    }

    @Bean
    public CacheResolver cacheResolver() {
        return new CustomCacheResolver(ehCacheManager, redissonCacheManager);
    }
}

 

CachingConfigurer 인터페이스를 구현하는 방식으로 구성했습니다.

ehCacheManager, redissonCacheManager를

@Configuration
@EnableCaching
public class MultipleCacheManagerConfig implements CachingConfigurer {

    private final CacheManager ehCacheManager;
    private final CacheManager redissonCacheManager;

    public MultipleCacheManagerConfig(@Qualifier("ehCacheManager") @Lazy CacheManager ehCacheManager,
                                      @Qualifier("redissonCacheManager") @Lazy CacheManager redissonCacheManager) {
        this.ehCacheManager = ehCacheManager;
        this.redissonCacheManager = redissonCacheManager;
    }

    @Lazy
    @Bean
    public CacheResolver cacheResolver() {
        return new CustomCacheResolver(ehCacheManager, redissonCacheManager);
    }
}

 

CustomCacheResolver를 구성했습니다

public class CustomCacheResolver implements CacheResolver {

    private final CacheManager ehCacheManager;
    private final CacheManager redissonCacheManager;

    public CustomCacheResolver(CacheManager ehCacheManager,
                               CacheManager redissonCacheManager) {
        this.ehCacheManager = ehCacheManager;
        this.redissonCacheManager = redissonCacheManager;
    }

    @Override
    public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
        // 캐시 이름을 기준으로 캐시 매니저를 선택
        String cacheName = context.getOperation().getCacheNames().iterator().next();
        if ("localCache".equals(cacheName)) {
            return Collections.singleton(ehCacheManager.getCache(cacheName));
        } else if ("globalCache".equals(cacheName)) {
            return Collections.singleton(redissonCacheManager.getCache(cacheName));
        }
        return Collections.emptyList();
    }
}

 

캐시호출하는 클라이언트 코드입니다

@Cacheable(cacheNames = "localCache",  cacheResolver = "cacheResolver")
public MemberDtoV2 getMemberById(Long id) {
    MemberV2 memberV2 = memberRepository.findById(id)
            .orElseThrow(() -> new IllegalArgumentException("Member not found with id: " + id));
    return MemberDtoV2.of(memberV2.getId(), memberV2.getEmail(), memberV2.getName());
}

 

 

참고 링크:

Using Multiple Cache Managers in Spring