DrunkenPope
DrunkenPope

Reputation: 576

Overlapping Spring bean names with inheritance

I have some sample code posted to github, so I won't include long code fragments here, please see for that: https://github.com/ralf-lackinger/spring-inheritance/tree/master

I have a Parent and a Child, both are Spring beans. When I want to retrieve the Parent via the BeanFactory by the bean's name, an instance of the Child is returned. This causes issues for me, since I want them to have different names and return only the specific, since the subclass overrides a method I use from the super class:

Parent names: parent, parentName1, parentName2
Child names: child, childName1, childName2

Short code sample, please see my github repository for the full code sample:
context.getBean("parentName1", Parent.class).print();
returns:
Print from child.

Maybe there is a solution to use qualifiers from Spring, but I'm not sure if this will work. I already tried the @Primary annotation, but didn't help me solve this issue.

I'm using:
java version "1.8.0_66"
Spring 4.2.3.RELEASE

EDIT:
I updated the github repository with a branch named 'fixed-name-conflict', where I included the changes I needed to make, to resolve my issue. See also the accepted answer (and the commons there) on more information.

Thanks @oailloud for his help.

EDIT 2:
The problematic parts were these methods:
Parent:

@Bean(name = {"parentName1", "parentName2"})
public Parent additionalBeanNames() {
    return new Parent();
}

and Child:

@Override
@Bean(name = {"childName1", "childName2"})
public Child additionalBeanNames() {
    return new Child();
}

Solutions was to rename to Child's method, so the child does not pick up the Parent's additional bean names.

Upvotes: 4

Views: 2263

Answers (1)

oailloud
oailloud

Reputation: 363

It's because you're overriding the method additionalBeanNames in your Child class. I guess Spring gets confused and creates a Child with the info from the Parent @Bean. Just rename additionalBeanNames() method in your Child class and name explictly the beans with @Bean(name="...").
And if you need to factorize code between these two methods, just extract it in a third protected method.

Also, watch out : you're creating two instances of each class. One because of the method annotated with @Bean, the other because of the @Component. In that case, the instance is named from the class name. That's why you have "parent" and "child" beans in your context.

Upvotes: 5

Related Questions