Как использовать @EnableCache, несколько CacheManager и пользовательский преобразователь кэша - PullRequest
1 голос
/ 11 июля 2019

Я пытаюсь получить два CacheManager Caffeine, один по умолчанию и один с именем ("new.kid").Именованный используется для определенного метода в классе NewKid и обозначается @Cacheable (cacheManager = "new.kid") в методе (настройки аннотации не могут быть изменены для цели этой проблемы).

Я определил пользовательский CacheResolver, переопределив getCacheNames, чтобы он возвращал имена кэша менеджера кэша new.kid для целей типа NewKid и имена кэша defautl в противном случае.

На самом деле нетмного информации об этом, но из того, что я собрал, если у вас есть более одного (по умолчанию) CacheManager, пользовательский CacheResolver является обязательным.Я определил пользовательский CacheResolver, переопределив getCacheNames, чтобы он возвращал имена кэша менеджера кэша new.kid для целей типа NewKid и имена менеджера кэша по умолчанию в противном случае.Полный пример (скопированный и измененный из Руководства по началу работы с Spring Caching) доступен в моем github https://github.com/tyonchev/spring-cache


    @Component
    public class NewKid {
        @Cacheable(cacheManager="new.kid")
        public String whatsYourName(String input){
            return "New Kid Name " + input;
        }
    }


    @Configuration
    public class NewKidCacheManager {
        @Bean("new.kid")
        public CacheManager newKidCacheManager() {
            CacheManager cmgr = new CaffeineCacheManager();
            ((CaffeineCacheManager) cmgr).setCacheNames(Arrays.asList(cacheName));
            ((CaffeineCacheManager) cmgr).setCaffeine(Caffeine.newBuilder());
            return cmgr;
        }
    }

    @Configuration
    @EnableCaching
    public class CacheManagerConfig extends CachingConfigurerSupport {
        @Autowired
        @Qualifier(value = "new.kid")
        CacheManager newKidCacheManager;

        @Bean
        @Override
        public CacheManager cacheManager() {
    ...
        }

        @Bean
        @Primary
        @Override
        public CacheResolver cacheResolver( ) {
            return new CustomResolver(newKidCacheManager);
        }


class CustomResolver extends AbstractCacheResolver {

    public CustomResolver(CacheManager newKidCacheManager) {
        this.newKidCacheManager = newKidCacheManager;
    }

    @Override
    protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> cacheOperationInvocationContext) {
        if (cacheOperationInvocationContext.getTarget() instanceof NewKid) {
            return newKidCacheManager.getCacheNames();
        } else {
            return getCacheManager().getCacheNames();
        }
    }
}

Если я использую аннотацию @EnableCaching, я застрял сSimpleCacheResolver, который полностью игнорирует мой CustomResolver, хотя и помечается @Primary @Bean.Это вызывает следующее исключение:


    No cache could be resolved for 'Builder[public java.lang.String hello.NewKid.whatsYourName(java.lang.String)] caches=[] | key='' | keyGenerator='' | cacheManager='new.kid' | cacheR
    esolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@171e2c13'. At least one cache should be provided per cache operation.

Если я удаляю @EnableCaching, загружается правильный CustomResolver, однако, конечно, @Cacheable полностью игнорируется, поэтому результаты метода не кэшируются

Ячто-то не так, или просто нельзя использовать и EnableCaching, и несколько CaceManager с пользовательским распознавателем?Как это происходит, я всегда застреваю с SimpleCacheResolver, даже если у меня есть другой компонент CacheResolver, помеченный как @Primary?Я был бы счастлив, если бы кто-нибудь мог указать мне правильное направление

...