当前位置: 首页 > 知识库问答 >
问题:

在我将方法移到同一个类后,Spring Boot@Cacheable停止工作

司徒茂实
2023-03-14

我正在我的项目中做一些重构,我面临着非常奇怪的问题。

我有一个服务类,负责从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());
    }

你知道怎么回事吗?

非常感谢你。

共有1个答案

应安国
2023-03-14

在查看可缓存源时,doc说:

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. 

这个片段与这个问题最相关的部分是建议的方法。为了使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注释的方法驻留在同一个类中。

 类似资料:
  • 我有一个巨大的java类文件,其中包含嵌套类编码的所有内容。在我按照我想要的方式完成所有工作之后,有了我需要的XML输出...我将嵌套类拆分到它们自己的类文件中。 但是,当我运行代码时,我的所有@XMLPath注释都被忽略了。只有javax.xml.bind.annotation.*中的本机版本仍然有效... 好吧..所以我把所有的嵌套类放回原样,重新运行代码,@xmlpath(实际上MOXy的东

  • 我在XAMPP中启动MYSQL时遇到了问题。Apache启动正常,但MYSQL不断报告意外关机。 我被引导删除,它在此之后工作,但它删除了我所有的数据库,并且MYSQL在我重新启动机器后再次停止工作。 [ERROR]INNODB:试图打开以前打开的表空间。以前的表空间MYSQL/INNODB_INDEX_STATS在FILEPATH:.\MYSQL\INNODB_INDEX_STATS.IBD中使

  • 从同一bean的另一个方法调用缓存的方法时,Spring缓存不工作。 这里有一个例子来清楚地解释我的问题。 配置: 缓存服务: 结果: 方法调用在第二次调用中使用缓存。但是,当在AService类中调用方法时(在中),Cache未被使用。 这就是SpringCache的工作原理还是我遗漏了什么?

  • 我试图更新我的网站从使用Laravel 5.4到Laravel 7.3。在大多数情况下,它是有效的,但看起来我的自定义门面由于某种原因不起作用... 无论何时使用一个,我都会得到以下错误。。。 这里是相关文件... 应用\助手\MyLogHelper.php 应用\提供商\MyLogServiceProvider.php App\Facades\MyLog。php 在app.php.... 提供商

  • 我有一个使用javax.swing和java.awt的图形用户界面,请求焦点是保持文本字段的焦点,这样用户就可以从键盘开始。然后,我为每个整数0-9添加了按钮,以及一个清晰的字段按钮。然而,现在的焦点总是从按钮开始。 当我单击一个按钮时,焦点仍然返回到文本字段,或者如果我启动焦点,它仍然保留在文本字段中,我如何解决这个问题,并在每次窗口打开时将焦点放在文本字段上? 数字按钮示例 文本字段代码 检查

  • 我已经将我们的项目迁移到androidx,现在该应用程序在API21及以上版本上运行,但在API21及以上版本下无法运行。这款应用正在使用multidexing,之前也一直在使用,运行良好。现在我只是得到一个致命的信号11和没有更多有用的日志时,应用程序崩溃。该系统在空气污染指数21或以上时仍然运作良好。你有什么线索或暗示我如何更接近解决这个问题吗?