我正在我的项目中进行一些重构,我面临着非常奇怪的问题。
我有这个服务类,负责从 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());
}
您知道可能出了什么问题吗?
非常感谢。
当查看可缓存源时,文档说:
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
。为了使 AOP 工作,您需要像以前一样组织代码。
为什么私有方法不能与AOP一起使用的解释:
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
Pablo 提供的链接解释了为什么调用方法不能与用
Cacheable
注释的方法驻留在同一类中。
本文提供了很好的解释和解决方案 - 替代解决方案