Hello,
I have accidentally named my worker @Component
class same as my main application class with @SpringBootApplication
and @ComponentScan
annotations. I have correct structure by documentation because my main class is in root package and other classes are in sub-packages.
Seems like my @Component
class is not being picked up by component scanning. It is in different package so I think this should work.
Spring version = 2.3.4.RELEASE. Build tool = Gradle 6.6.1
Thanks.
Comment From: philwebb
This is an interesting issue. It appears that ClassPathBeanDefinitionScanner.checkCandidate returns false
due to the result of isCompatible
. This means that ConflictingBeanDefinitionException
is not thrown and the duplicate bean definition is never registered.
Spring Boot does set DefaultListableBeanFactory.setAllowBeanDefinitionOverriding
to false, so it seems odd that we're not getting a clear exception.
I'm going to transfer this issue to the Spring Framework team to see if there's anything that can be done to improve the situation.
Comment From: sbrannen
Does using FullyQualifiedAnnotationBeanNameGenerator
help?
Comment From: philwebb
I'm sure that would work-around the issue, but it still feels strange that we don't get an exception when setAllowBeanDefinitionOverriding
is false
.
Comment From: sbrannen
I'm sure that would work-around the issue, but it still feels strange that we don't get an exception when
setAllowBeanDefinitionOverriding
isfalse
.
Understood.
I'm tentatively slating this for 5.3.1 for further investigation.
Comment From: jhoeller
I suppose it's the !(existingDefinition instanceof ScannedGenericBeanDefinition)
check that makes it indicate compatibility here, looking like there was an explicit bean of the same name registered before (which we can consider an override for a scanned bean definition of the same name). Usually those overriding beans would be user-defined, but it looks like the Boot application instance is registered the same way?
Comment From: Drezir
Does it make sense to put additional if statement in to org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
? That statement may throw a BeanDefinitionOverrideException
if bean of the same name and of type AnnotatedGenericBeanDefinition
does exist in registry (we could also check if candidate is type of ScannedGenericBeanDefinition
)?
For this purpose it looks like that the code
if (!this.registry.containsBeanDefinition(beanName)) {
return true;
}
harms this usecase and by removing it we may get ConflictingBeanDefinitionException
but I do not know if we could cause any other troubles by deleting this.
I think that in this case it should not fail on BeanDefinitionOverrideException
. ConflictingBeanDefinitionException
makes sense to me more.
Or probably, checkCandidate
may be extended to not control bean in registry only by name but also by simple type?