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

多依赖共用Caffeine缓存时缓存找不到异常的解决方法

解决方案:Spring多依赖缓存冲突处理

问题根源

你的应用中,依赖A的缓存配置仅初始化了名为user的缓存,而依赖B的@Cacheable注解引用了未被初始化的security.remotePublicKeyCache缓存名;同时若容器中存在多个CacheManager Bean且未指定默认实例,Spring无法自动匹配到正确的缓存管理器,导致抛出找不到缓存的异常。


可行方案

方案1:扩展默认缓存管理器,支持动态创建缓存

修改依赖A的缓存配置,将其标记为默认缓存管理器,并允许动态创建任意缓存名(默认开启,可显式声明),这样所有未指定缓存管理器的@Cacheable都会复用该实例,并自动创建所需缓存:

@Configuration
@EnableCaching
public class CaffeineConfiguration {

  @Primary // 标记为默认缓存管理器
  @Bean(name="myCacheManager")
  public CacheManager cacheManager() {
      // 不指定初始缓存名,或同时包含A和B的缓存名
      CaffeineCacheManager cacheManager = new CaffeineCacheManager();
      cacheManager.setDynamic(true); // 显式开启动态创建(默认值为true,可省略)
      cacheManager.setCaffeine(caffeineConfig());
      return cacheManager;
  }

  @Bean(name = "myCaffeineConfig")
  public Caffeine caffeineConfig() {
      return Caffeine.newBuilder()
              .expireAfterAccess(5, TimeUnit.MINUTES);
  }
}

方案2:配置多缓存管理器,通过CacheResolver路由

若依赖A和B需要不同的缓存配置(如过期时间),可创建两个独立的CacheManager,并自定义CacheResolver根据缓存名自动匹配对应的管理器:

@Configuration
@EnableCaching
public class MultiCacheConfiguration implements CachingConfigurer {

  // 依赖A专属缓存管理器
  @Bean(name="myCacheManager")
  public CacheManager userCacheManager() {
      CaffeineCacheManager cacheManager = new CaffeineCacheManager("user");
      cacheManager.setCaffeine(userCaffeineConfig());
      return cacheManager;
  }

  // 依赖B专属缓存管理器
  @Bean(name="dependencyBCacheManager")
  public CacheManager dependencyBCacheManager() {
      CaffeineCacheManager cacheManager = new CaffeineCacheManager("security.remotePublicKeyCache");
      cacheManager.setCaffeine(dependencyBCaffeineConfig());
      return cacheManager;
  }

  @Bean(name = "myCaffeineConfig")
  public Caffeine userCaffeineConfig() {
      return Caffeine.newBuilder()
              .expireAfterAccess(5, TimeUnit.MINUTES);
  }

  @Bean(name = "dependencyBCaffeineConfig")
  public Caffeine dependencyBCaffeineConfig() {
      // 可根据依赖B的需求自定义缓存配置
      return Caffeine.newBuilder()
              .expireAfterAccess(30, TimeUnit.MINUTES);
  }

  // 自定义缓存解析器,按缓存名路由
  @Override
  public CacheResolver cacheResolver() {
      return new SimpleCacheResolver() {
          @Override
          protected Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
              String cacheName = context.getOperation().getCacheNames().iterator().next();
              ApplicationContext ctx = getApplicationContext();
              if ("security.remotePublicKeyCache".equals(cacheName)) {
                  return Collections.singleton(ctx.getBean("dependencyBCacheManager", CacheManager.class).getCache(cacheName));
              }
              return Collections.singleton(ctx.getBean("myCacheManager", CacheManager.class).getCache(cacheName));
          }
      };
  }
}

方案3:提前初始化所有依赖的缓存名

若无需区分缓存配置,可直接在缓存管理器中初始化所有需要的缓存名(包括依赖B的),启动时一次性创建所有缓存:

@Configuration
@EnableCaching
public class CaffeineConfiguration {

  @Primary
  @Bean(name="myCacheManager")
  public CacheManager cacheManager() {
      // 同时初始化依赖A和B的缓存名
      CaffeineCacheManager cacheManager = new CaffeineCacheManager("user", "security.remotePublicKeyCache");
      cacheManager.setCaffeine(caffeineConfig());
      return cacheManager;
  }

  @Bean(name = "myCaffeineConfig")
  public Caffeine caffeineConfig() {
      return Caffeine.newBuilder()
              .expireAfterAccess(5, TimeUnit.MINUTES);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:45:30