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

Spring Boot默认未启用自定义KeyGenerator问题咨询

自定义KeyGenerator的配置细节与生效逻辑说明

看起来你已经完成了自定义KeyGenerator的开发,并且确认配置类已经通过Gradle依赖成功加载、Bean实例也已创建,但目前只有在@Cacheable注解显式指定keyGenerator属性时才会触发这个自定义实现。我先把你的配置代码格式化出来,再给你拆解背后的逻辑和调整建议:

你的配置类格式化代码

@EnableCaching
@Configuration
public class CacheKeyConfig extends CachingConfigurerSupport {
    private static final Logger LOGGER = LoggerFactory.getLogger(CacheKeyConfig.class);

    @Bean
    @Primary
    public KeyGenerator keyGenerator(@Autowired(required = false) SomeDependency dependency) {
        // 这里是你的自定义KeyGenerator逻辑(示例实现供参考)
        return (target, method, params) -> {
            StringBuilder keyBuilder = new StringBuilder();
            keyBuilder.append(target.getClass().getSimpleName())
                      .append(".")
                      .append(method.getName());
            for (Object param : params) {
                keyBuilder.append("-").append(param);
            }
            String generatedKey = keyBuilder.toString();
            LOGGER.debug("Generated custom cache key: {}", generatedKey);
            return generatedKey;
        };
    }
}

(注:补全了你代码中截断的@Autowired(requir...部分,你可以根据实际依赖替换SomeDependency)

为什么当前仅显式指定才生效?

你现在的配置是通过@Bean来声明KeyGenerator,并且加了@Primary注解,但因为你继承了CachingConfigurerSupport,这里有个容易踩的坑:

Spring Cache默认会优先使用CachingConfigurer实现类中重写的方法来获取默认的缓存组件(包括KeyGenerator),而不是直接取容器中的@Primary Bean。也就是说,如果你只是用@Bean声明了KeyGenerator,但没有重写CachingConfigurerSupport的keyGenerator()方法,Spring还是会用它自己的默认KeyGenerator实现,只有当你在@Cacheable中显式指定keyGenerator属性时,才会找到你的自定义Bean。

两种调整方案

方案1:让自定义KeyGenerator成为全局默认

如果你希望所有@Cacheable注解在不指定keyGenerator时都自动使用你的自定义实现,只需要把配置改成重写父类的keyGenerator()方法即可:

@EnableCaching
@Configuration
public class CacheKeyConfig extends CachingConfigurerSupport {
    private static final Logger LOGGER = LoggerFactory.getLogger(CacheKeyConfig.class);

    @Autowired(required = false)
    private SomeDependency dependency;

    @Override
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            // 你的自定义key生成逻辑
            StringBuilder keyBuilder = new StringBuilder();
            keyBuilder.append(target.getClass().getSimpleName())
                      .append(".")
                      .append(method.getName());
            for (Object param : params) {
                keyBuilder.append("-").append(param);
            }
            String generatedKey = keyBuilder.toString();
            LOGGER.debug("Generated custom cache key: {}", generatedKey);
            return generatedKey;
        };
    }
}

这样配置后,所有未指定keyGenerator的@Cacheable都会自动使用你的自定义实现。

方案2:保持仅显式指定时生效(符合你的当前需求)

如果你就是想让这个自定义KeyGenerator只在主动指定时被使用,那么可以做两个小调整:

  1. 去掉@Primary注解,避免干扰Spring默认的KeyGenerator
  2. 在需要使用的地方,通过Bean名称指定:
@Cacheable(value = "userCache", keyGenerator = "keyGenerator")
public User getUserById(Long id) {
    // 业务逻辑
}

(这里的"keyGenerator"是你Bean的名称,默认和方法名一致,如果你改了方法名,要对应调整)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:33:40