0

Considering the following configuration class which declares two beans, bean B which should only be created on conditional of bean A.

@Configuration(
    proxyBeanMethods = false
)
@AutoConfigureBefore(SomeOtherCOnfig.class)
@ConditionalOnProperty(name = "prop",havingValue = "false")
public class SomeConfiguration {

@Bean("beanA")
BeanA beanA() {
if (someCOndition){
   return null;
}
   return new BeanA();
}


@ConditionalOnBean(name = "beanA")
@Bean(name = "beanB")
BeanB beanB(@Qualifier("beanA") BeanA beanA) {
    return new BeanB(beanA);
}

When someCondition is true I expect beanA not to be matched in the autoconfiguration report thus mean beanB creation is never attempted to be executed. The behaviour i see is, beanA is considered a positive match in the autoconfiguration

SomeConfiguration#beanB matched:- @ConditionalOnBean (names: beanA; SearchStrategy: all) found bean 'beanA' (OnBeanCondition)

and beanB is attempted to be created and as I expect happens the exception thrown Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type

Why is the beanA considered to be in the beanFactory here during autoconfiguration but also not there either when injecting dependencies?

Is it because the bean is there, or at least a reference of type which points to null null? But if that is the case shouldn't spring be injecting a null bean to beanB

Nanotron
  • 554
  • 5
  • 16
  • Why wouldn't it? Returning `null` doesn't make the bean not exists, spring will create a `NullBean` (to support returning `null` from an `@Bean` method) which makes the bean definition exists (hence the conditionalonbean will succeed) but retrieving it will lead to `null`. Instead of an if you shoulduse an `@ConditionalOn...` that suites your need to prevent the bean from being created. – M. Deinum Mar 17 '22 at 19:12
  • Ok I understand that explanation but why does the bean definition not exist when its being injected. Why is the particular exception `org.springframework.beans.factory.NoSuchBeanDefinitionException` when injected while during the autoconfiguration process the bean definition did exist for it to be matched. – Nanotron Mar 18 '22 at 13:10
  • 1
    Because it is a `NullBean`. So it does exist but this case is handled in a special way, which can be confusing. But generally speaking you shouldn't be returning `null` from an `@Bean` method. The `NullBean` is particularly useful when using an `ObjectProvider` and its methods. – M. Deinum Mar 18 '22 at 13:32
  • I agree and ultimately I feel usages of returning `null` is a design flaw unless really unavoidable in some cases although I have seen cases of it in the spring framework `org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration` for example. Can you provide any examples of where returning `NullBean` is dangerous? I didnt realise Spring internally created a `org.springframework.beans.factory.support.NullBean` so thanks for sharing that. – Nanotron Mar 18 '22 at 19:56
  • I don't see where the `DataSourceAutoConfiguration` returns `null`? However the `NullBean` was introduced with [this](https://github.com/spring-projects/spring-framework/issues/20384) (IIRC). – M. Deinum Mar 19 '22 at 08:33

0 Answers0