When a @Bean
factory returns null
, a NullBean
is registered in the context that's not meant to be considered when looking for a candidate by type (only a lookup by name would return it).
Unfortunately, that does not work in at least two cases:
org.springframework.beans.factory.config.AutowireCapableBeanFactory#resolveNamedBean
will return suchNullBean
for the type it has been defined againstorg.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType(org.springframework.core.ResolvableType, boolean, boolean)
will do that (used by Spring Boot's@ConditionalOnMissingBean
.
This was original raised in https://github.com/spring-projects/spring-boot/issues/24448 that contains a sample project.
Comment From: jhoeller
I have revised resolveNamedBean
to consistently treat NullBean
as not existing, to be committed soon.
However, getBeanNamesForType
cannot really handle null return values since we cannot assume that the factory methods have been called at that point. For consistent behavior, we have to include NullBean
definitions even when resolved already. As a caller, you'd have to explicitly call getBean
for each such candidate and do .equals(null)
to find out whether it's a null stub.
Comment From: jhoeller
I wonder whether this resolveNamedBean
revision would be needed in 5.2.x as well? It's a high-risk area for subtle regressions, so I'd only do it if Boot 2.3.x actually runs into such scenarios as well.
Comment From: snicoll
The related link is a long standing issue and I am surprised this wasn't raised before, actually. Let me see if there is a workaround first. If there is one we'll document. That sounds a better option than backporting to me.
Comment From: jhoeller
Actually, backporting to 5.2.13 with a release target in February, with the change getting road-tested in the 5.3.3 release in January first, feels ok to me. Backporting is a worthwhile option if this is a common enough problem.