Why boolean matches(...) method in SpecificCaseCondition class is invoked 2 times ? I expect it to be invoked only once, on AnyConfiguration creation. In fact, it's invoked 2 times.
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();
}
}
CodePudding user response:
When Spring Boot auto-configures the beans for the app context, it does so in multiple phases. By default, condition at the class level* will be evaluated multiple times, for each phase. That's probably why you're seeing your custom Condition
method being called more than once; Spring is invoking it during each phase.
One way to avoid that would be to annotate the @Bean
methods with @Conditional
instead of the entire class. Like this:
@Configuration
public class AnyConfiguration {
@Bean
@Conditional(SpecificCaseCondition.class)
public Service firstService() {
return new RealService();
}
@Bean
@Conditional(SpecificCaseCondition.class)
public Service secondService() {
return new RealService();
}
@Bean
@Conditional(SpecificCaseCondition.class)
public Service thirdService() {
return new RealService();
}
}
In my experiments, method-level conditions are only evaluated during the REGISTER_BEAN
phase.
There is a downside to this solution, of course - it isn't very DRY. As an alternative, you can change your condition to implement ConfigurationCondition
which has a method, public ConfigurationPhase getConfigurationPhase()
, to dictate which phase the condition should be evaluated in.
- The various
@Conditional*
annotations can be placed at the class level or the method level.