problem
For classes annotated with both @Component
and @conditionalonmissingBean
The corresponding Beandifinition will be registered by @ComponentScan
,
Then be onfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
removed,
This will cause some problems.
sample
full example code:https://github.com/Hccake/demo-condition
Some sample code is shown below:
@Component
@ConditionalOnMissingBean(AService.class)
public class AService{
}
@Configuration
public class DemoConfiguration {
@Bean
@ConditionalOnBean(AService.class)
public AController aController(AService aService){
return new AController(aService);
}
}
error log
Positive matches:
-----------------
DemoConfiguration#aController matched:
- @ConditionalOnBean (types: com.example.biz.service.AService; SearchStrategy: all) found bean 'AService' (OnBeanCondition)
Negative matches:
-----------------
AService:
Did not match:
- @ConditionalOnMissingBean (types: com.example.biz.service.AService; SearchStrategy: all) found beans of type 'com.example.biz.service.AService' AService (OnBeanCondition)
Parameter 0 of method aController in com.example.demo.condition.DemoConfiguration required a bean of type 'com.example.biz.service.AService' that could not be found.
It can be seen that the matching judgment of AController and Aservice for the same bean Aservice
has completely different results
The problem code
class ConfigurationClassBeanDefinitionReader {
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
// Omit some .......................
}
}
When the condition check fails, the original beanDefinition is deleted ,
Whether can make a judgement here, if the current configurationClass is original beanDefinition beanClass, don't delete?
Comment From: snicoll
@ConditionalOnMissingBean
is a Spring Boot concept, and its javadoc states that such conditions should be added on auto-configurations only. You're mixing auto-configuration and user-configuration.
See also #29372