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