Я делаю небольшой рефакторинг в своем проекте, и я столкнулся с очень странной проблемой.
У меня есть этот сервисный класс, который занимается получением и анализом данных из 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());
}
У вас есть идеи, что может быть не так?
Большое спасибо.
При просмотре источника 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
.
Спасибо за ваше объяснение. Я перенес эту логику обратно в дополнительный класс, и она отлично работает. Спасибо за ваше время!
Возможно, этот пост сможет ответить и на ваш вопрос: stackoverflow.com/questions/12115996/…