为何@Conditional的matches方法被调用2次?预期仅执行一次
Spring中@Conditional注解的Condition#matches方法被调用两次的原因与解决办法
当使用Spring框架时,标记了@Conditional(SpecificCaseCondition.class)的AnyConfiguration配置类在初始化过程中,SpecificCaseCondition中的matches方法被执行了两次,但预期仅执行一次。相关代码如下:
public class SpecificCaseCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return true; } } @Configuration @Conditional(SpecificCaseCondition.class) public class AnyConfiguration { @Bean public Service firstService() { return new RealService(); } @Bean public Service secondService() { return new RealService(); } @Bean public Service thirdService() { return new RealService(); } }
原因分析
Spring在处理配置类时,存在两次调用Condition检查的标准流程:
- 第一次是配置类候选性筛选阶段:Spring扫描到配置类后,会先调用
matches方法判断该配置类是否有资格被纳入Spring上下文的候选列表。 - 第二次是配置类Bean定义解析阶段:当确认配置类可被处理后,Spring在解析配置类内的
@Bean方法等内容时,会再次触发Condition检查,确保当前环境依然满足配置类的生效条件(防止两次检查之间环境参数发生变化)。
解决办法
- 添加结果缓存(适用于判断逻辑不依赖动态环境的场景)
如果你的Condition判断逻辑是固定的、不依赖动态变化的环境参数,可以在Condition类中加入缓存逻辑,避免重复执行判断:
public class SpecificCaseCondition implements Condition { private static Boolean cachedMatchResult; @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { if (cachedMatchResult == null) { // 这里替换为实际的条件判断逻辑 cachedMatchResult = true; } return cachedMatchResult; } }
- 接受框架的设计机制(适用于依赖动态环境的场景)
如果你的Condition判断依赖于可能动态变化的环境参数,无法使用缓存,那么需要接受Spring的两次调用——这是框架为了保证配置类生效准确性的设计,属于正常行为。
内容的提问来源于stack exchange,提问作者Artem Causelove
相关产品推荐
相关产品推荐

