programing

스프링 캐시 Java에서 여러 캐시 매니저 구성을 사용하는 방법

elseif 2023. 3. 20. 21:36

스프링 캐시 Java에서 여러 캐시 매니저 구성을 사용하는 방법

웹 어플리케이션에서 여러 스프링 캐시 매니저를 설정하고 프로젝트의 다양한 장소에서 다른 캐시 매니저를 사용할 수 있도록 하고 싶습니다.이거 어떻게 할 수 있는 방법이?

여기에는 여러 가지 방법이 있으며 올바른 답은 캐시 사용에 따라 달라집니다.

"기본" 캐시 관리자가 있습니다.

사용 사례의 90%에 CacheManager A를 사용하고 10%에 B를 사용하는 경우 기본값을 생성하는 것이 좋습니다.CacheManagerA의 경우(를 사용하여 지정해야 합니다).CacheConfigurerSupport예를 들어 다음과 같습니다.

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    @Override
    @Bean // not strictly necessary
    public CacheManager cacheManager() { ... CacheManager A }

    @Bean
    public CacheManager bCacheManager() { ... CacheManager B }
}

그 후 10%의 사용 사례에 대해CacheConfig다른 캐시 매니저를 사용해야 하는 클래스의 최상위에 있습니다.

@CacheConfig(cacheManager="bCacheManager")
public class MyService { /*...*/ }

다른 캐시 매니저를 하나의 메서드에만 사용해야 하는 경우 메서드 수준에서도 지정할 수 있습니다.

@Cacheable(cacheNames = "books", cacheManager = "bCacheManager")
public Book findById(long id) { /*...*/ }

보다 세밀한 해상도

이 상황이 아니라면 어떤 캐시 매니저를 사용해야 하는지 케이스 바이 케이스로 알 수 있는 방법이 필요합니다.이것은, 타겟 타입에 근거해 실시할 수 있습니다(MyService또는 캐시 이름(books를 실장할 필요가 있습니다.CacheResolver그렇게 번역할 수 있습니다.

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    @Override
    public CacheResolver cacheResolver() { ... }
}

의 javadoc을 확인합니다.CacheResolver자세한 것은, 을 참조해 주세요.실장에서는, 다음의 몇개의 기능이 있는 경우가 있습니다.CacheManager사용할 매니저를 결정하기 위해 로직에 따라 내부적으로 호출하는 인스턴스(빈 또는 비빈)입니다.

댓글에서 '모듈'을 말하는 걸 봤어요.캐슁은 실제로 인프라스트럭처의 문제이기 때문에 애플리케이션 레벨에서 이러한 결정을 내릴 것을 강력히 권장합니다.캐시에 "로컬" 태그를 붙이고 다른 캐시에 "클러스터" 태그를 붙일 수 있습니다.하지만 이름을 쉽게 하기 위해서는 어떤 명명법이 필요합니다.모듈 수준에서 캐시 매니저를 선택하지 마십시오.

이 블로그 투고는 다른 예시와 함께 이를 설명하고 있습니다.

@Stephane Nicoll의 설명에 따르면 몇 가지 옵션이 있습니다.세관에 대한 정보를 알려드리겠습니다.CacheResolver.CacheResolver에는, 다음의 1개의 방법이 있습니다.

Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context);

캐시 가능한 연산의 클래스, 메서드, 인수 등에 컨텍스트를 제공합니다.

기본 형식:

public class CustomCacheResolver implements CacheResolver {

    private final CacheManager cacheManager;

    public CustomCacheResolver(CacheManager cacheManager){
        this.cacheManager = cacheManager;
    }

    @Override
    public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
        Collection<Cache> caches = getCaches(cacheManager, context);
        return caches;
    }

    private Collection<Cache> getCaches(CacheManager cacheManager, CacheOperationInvocationContext<?> context) {
        return context.getOperation().getCacheNames().stream()
            .map(cacheName -> cacheManager.getCache(cacheName))
            .filter(cache -> cache != null)
            .collect(Collectors.toList());
    }
}

여기 하나 쓰고 있어요.CacheManager간결하게.하지만 다른 바인딩을 할 수 있습니다.CacheManager~에 대해서CacheResolver보다 세밀한 선택을 할 수 있습니다.클래스명이X , 을 사용합니다.GuavaCacheManager그의 경우는 , 을 사용합니다.EhCacheCacheManager

마친 해야 합니다.CacheResolver ( 한 번 더 바인드할 수 )CacheManagers : 기기) :

@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {

    @Bean
    @Override
    public CacheManager cacheManager() {
        // Desired CacheManager
    }

    @Bean
    @Override
    public CacheResolver cacheResolver() {
        return new CustomCacheResolver(cacheManager());
    }
}

마지막로 '''를 해야 합니다.CustomCacheResolver의의 @Cacheable,@CachePut,@CacheConfig석석등 。

@Cacheable(cacheResolver="cacheResolver")

코드 샘플은 이쪽에서 확인하실 수 있습니다.

고객님의 CacheManager bean을 다음과 같이 쓸 수 있습니다.

    @Primary
    @Bean("customerCacheManager")
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        Map<String, Long> expires = new HashMap<>();
        expires.put("fundShareSplit", TimeUnit.SECONDS.toSeconds(60));
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        cacheManager.setExpires(expires);
        List<String> cacheNames = Arrays.asList("fundShareSplit");
        cacheManager.setCacheNames(cacheNames);
        return cacheManager;
    }

그럼 이걸 이렇게 기념품에 쓰세요.

 @Cacheable(cacheManager = "customerCacheManager",value = "fundShareSplit",key="'smile:asset:fundSplit:fundId:'+#root.args[0]+'_localDate:'+#root.args[1]",unless="#result == null")

언급URL : https://stackoverflow.com/questions/38570211/how-to-have-multiple-cache-manager-configuration-in-spring-cache-java