Spring 启动中 @ConditionalOnBean 的时机陷阱
1. 启动流程组件扫描 vs 自动配置Spring 启动大致分两段组件扫描Component Scan扫到Service/Component时立刻评估类上的ConditionalOnBean决定「要不要注册这个 Bean 定义」。自动配置Auto‑Configuration更晚才跑RedisAutoConfiguration这时才会创建StringRedisTemplate。StringRedisTemplate来自自动配置RedisRateLimitService若是被scanBasePackages扫进去的Service条件会在第 1 步就判完。当时容器里通常还没有StringRedisTemplate→ 条件为false→ 这个类的 Bean 定义直接被丢掉。后面即使 Redis 配好了、StringRedisTemplate创建成功也不会回头再评估一次。所以会出现Redis 明明通限流 Bean 却永远不存在。2.ConditionalOnBean的正确存放位置写法时机ServiceConditionalOnBean扫描阶段判定往往早于依赖 BeanAutoConfiguration/ConfigurationBeanConditionalOnBean自动配置阶段判定此时StringRedisTemplate通常已在官方也建议ConditionalOnBean用在 auto‑config 的Bean方法上不要挂在被 component‑scan 扫到的Component/Service上。3. 与「直接注入StringRedisTemplate」的对比像RefreshTokenService这种ServicepublicclassRefreshTokenService{privatefinalStringRedisTemplatestringRedisTemplate;}没有ConditionalOnBean扫描只会登记「需要这个依赖」真正实例化时依赖已就绪所以能正常工作。出问题的是用条件注解在扫描期决定「要不要这个类」而不是「创建时再解析依赖」。4. 一句话总结判定过早 条件在「扫类」时就定生死而StringRedisTemplate要等「自动配置」才出现一次false就永久不创建。