Spring Boot @Cacheable перестал работать после того, как я переместил метод в тот же класс

Я делаю небольшой рефакторинг в своем проекте, и я столкнулся с очень странной проблемой.

У меня есть этот сервисный класс, который занимается получением и анализом данных из API. До рефакторинга у меня был специальный класс только для этого метода кеша, теперь я перенес его сюда, но он вдруг перестал работать. (Когда я устанавливаю точку останова внутри метода кеша, он вызывается каждый раз, когда я вызываю этот метод, раньше он вызывался только в первый раз, а затем возвращал значение из кеша)

Вот мой класс обслуживания:

    private static final String TRANSPORT_LOCATIONS = "transportLocations";
    private static final String CACHE_MANAGER = "cacheManager";
    private static final String ROOT_METHOD_NAME = "#root.methodName";
    private static final int FALLBACK_TIMEOUT = 1000;

    ...

    @Override
    public List<TransportLocation> fetchAllTransportsLocations() throws Exception {
        final var bodyStructure = createTransportLocationBody();
        final String body = buildBody(bodyStructure);
        final String url = transportLocationApiUrl + getCurrentTimeStamp();
        final HttpResponse<String> response = getTransportsLocations(url, body);
        if (isResponseBad(response.statusCode())) {
            LOG.error(GET_TRANSPORT_LOCATION_BAD_REQUEST_ERROR_MESSAGE);
            return createEmptyList();
        }
        return mapTransportsLocationsResponse(response.body());
    }

    @Cacheable(value = TRANSPORT_LOCATIONS, cacheManager = CACHE_MANAGER, key = ROOT_METHOD_NAME, sync = true)
    private HttpResponse<String> getTransportsLocations(final String url, final String body) throws Exception {
        HttpResponse<String> response = httpService.sendPostRequestWithBody(url, body);
        if (isResponseBad(response.statusCode())) {
            response = handleBadRequest(url, body);
        }
        return response;
    }

    private HttpResponse<String> handleBadRequest(final String url, final String body) throws Exception {
        LOG.error(GET_TRANSPORT_LOCATION_CACHE_BAD_REQUEST_ERROR_MESSAGE);
        Thread.sleep(FALLBACK_TIMEOUT);
        return httpService.sendPostRequestWithBody(url, body);
    }

Вот мой класс cacheConfig

    @Bean
    public net.sf.ehcache.CacheManager ehCacheManager() {
        final CacheConfiguration transportLocationCache = new CacheConfiguration();
        final net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();

        transportLocationCache.setName(CACHE_NAME);
        transportLocationCache.setMaxEntriesLocalHeap(ENTRIES_LOCAL_HEAP);
        transportLocationCache.setMemoryStoreEvictionPolicy(LRU);
        transportLocationCache.setTimeToLiveSeconds(TTL_SECONDS);
        config.addCache(transportLocationCache);

        return net.sf.ehcache.CacheManager.newInstance(config);
    }

    @Bean
    @Override
    public CacheManager cacheManager() {
        return new EhCacheCacheManager(ehCacheManager());
    }

У вас есть идеи, что может быть не так?

Большое спасибо.

Возможно, этот пост сможет ответить и на ваш вопрос: stackoverflow.com/questions/12115996/…

Pablo Andrés Rodas Giraldo 22.12.2020 17:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
551
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При просмотре источника Cacheable документ говорит:

Annotation indicating that the result of invoking a method (or all methods in a class) 
can be cached.
Each time an advised method is invoked, caching behavior will be applied, checking 
whether the method has been already invoked for the given arguments. 

Наиболее релевантная часть этого фрагмента для этого вопроса — advised method. Чтобы заставить АОП работать, вам нужно организовать код, как вы это делали раньше.

Объяснение того, почему закрытые методы нельзя использовать с АОП:

Because private methods are not inherited by subclasses, i.e. there is no way to 
intercept a private method and then delegate to it because the subclass cannot even 
call that method. This is a normal Java limitation and has nothing to do with AOP specifically.

https://stackoverflow.com/a/59961404/14072498

Ссылка, предоставленная Пабло, объясняет, почему вызывающий метод не может находиться в том же классе, что и метод, аннотированный Cacheable.

Спасибо за ваше объяснение. Я перенес эту логику обратно в дополнительный класс, и она отлично работает. Спасибо за ваше время!

Petr Jelínek 22.12.2020 19:09

Другие вопросы по теме