You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cache:@Scheduled调用方法中@CachePut失效,手动put正常

Spring Cache中@CachePut注解在定时任务调用时未生效的原因分析

在Spring Cache环境下,尝试在updateCategoryCacheForCountry方法上使用@CachePut注解但未生效,不过通过CacheManager手动调用put方法能正常更新缓存。该方法由@Scheduled注解的定时任务调用,可能的原因如下:

相关代码

业务方法

//    @CachePut(key = "#country")
public CacheCategories updateCategoryCacheForCountry(String country) {
    CacheCategories categories = requestDirectus(country);

    Cache categoriesCache = cacheManager.getCache("categories");
    categoriesCache.put(country, categories);

    return categories;
}

定时任务方法

@Scheduled(fixedDelay = 300000) // 5分钟
protected void updateCategories() {
    String[] countries = {esConfig.getStoreArgentina(), esConfig.getStoreChile(), esConfig.getStoreParaguay(), esConfig.getStoreBolivia()};

    for (String country : countries) {
        updateCategoryCacheForCountry(country);
    }
}

缓存配置类

@EnableCaching
@Configuration
@EnableScheduling
public class CacheConfig {
    
  @Bean // 配置使用的缓存
  public CacheManager cacheManager() {
      SimpleCacheManager cacheManager = new SimpleCacheManager();
      cacheManager.setCaches(Arrays.asList(
        new ConcurrentMapCache("categories"),
        new ConcurrentMapCache("token")
      ));
      return cacheManager;
  }
}

可能的原因

  • 内部方法调用绕过代理:Spring Cache的注解依赖AOP代理实现,当同一个类中的updateCategories(定时任务)直接调用updateCategoryCacheForCountry时,属于内部方法调用,不会经过Spring代理对象,导致@CachePut的切面逻辑无法触发。
  • @CachePut注解配置不全:原注释的@CachePut(key = "#country")未指定cacheNames或value属性,Spring无法定位要更新的缓存实例,即使代理生效也无法正常工作。正确写法应为@CachePut(cacheNames = "categories", key = "#country")。
  • 非public方法无法被代理增强:Spring AOP默认不对非public方法生成代理增强,若updateCategoryCacheForCountry不是public权限,注解逻辑不会生效(当前代码中方法为public,此点可排除,但需注意该规则)。

内容的提问来源于stack exchange,提问作者Nicolas Zaeta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:32:45