问题
I've got two classes:
package package1;
@Component
public class MyClass1 {
...
package package2;
@Component
public class MyClass1 {
...
When I run failsafe (in maven) - I get the following error in spring (that I don't get in surefire):
test1(package3.MyIntegrationTest) Time elapsed: 6.737 sec <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException:
Annotation-specified bean name 'myClass1' for bean class [packaging1.MyClass1] conflicts
with existing, non-compatible bean definition of same name and class [package2.MyClass1]
I get that to solve this I could get different Class names - or I could even specify
@Component(name="MyClass1a")
and
@Component(name="MyClass1b")
Or I could even set the package-scan
to only package1
.
(ie there are three ways to solve this that are obvious - but that's not my question).
That is NOT what I'm asking. (Ie this is not a duplicate).
Now to me - they should only clash in spring if they have the same package name. Surely Spring is smart enough to give them different shortened names if they have different packages?
My question is: Why would Spring 3 @Component names clash when they have different packages?
回答1:
As far as I know, spring's default naming scheme for beans is as follows (see the docs for AnnotationBeanNameGenerator)
package1.MyClass1 -> myClass1
package2.MyClass1 -> myClass1
The package name is stripped, and the first character is lowercased. Only way I know of around this would be to name the beans manually using the optional value
of @Component
, or via beans.xml
or an @Bean
annotated config method (or possibly implement your own BeanNameGenerator
).
Something to note, inner classes will retain the name of their outer class as part of the bean name since the class shortname is used eg:
package1.MyClass1.MyInnerClass -> myClass1.MyInnerClass
This can cause problems when autowiring by name since the bean name contains a period.
回答2:
Without explicit name specification, the detected bean will get a default name derived from the name of its class, without the package name, therefore two beans with the same name would be created which will throw an exception.
You should specify a different name for each @Component
if you have multiple classes with the same name.
来源:https://stackoverflow.com/questions/41259851/why-would-spring-3-component-names-clash-when-they-have-different-packages