Spring Boot默认未启用自定义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只在主动指定时被使用,那么可以做两个小调整:
- 去掉
@Primary注解,避免干扰Spring默认的KeyGenerator - 在需要使用的地方,通过Bean名称指定:
@Cacheable(value = "userCache", keyGenerator = "keyGenerator") public User getUserById(Long id) { // 业务逻辑 }
(这里的"keyGenerator"是你Bean的名称,默认和方法名一致,如果你改了方法名,要对应调整)
内容的提问来源于stack exchange,提问作者Don Rhummy

