Reputation: 1656
I have a parent class
package com.org.pages.home;
@Component
public class HomePage extends BasePage {
}
I have a sub-class
package com.org.pages.home;
@Component
public class WebHomePage extends HomePage {
}
When I try to get an instance of HomePage in the following manner:
T page = applicationContext.getBean(registeredClass);
//Here registeredClass is of the type Class<T> and contains reference to com.org.pages.home.HomePage
It throws an exception:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.org.pages.home.HomePage' available: expected single matching bean but found 2: homePage,webHomePage
Questions
1. Why am I seeing this exception when I am clearly passing the class that I want to get a bean for?
2. How can I fix this? Please note that I cannot autowire these classes anywhere as there are around 40 of them, which is why I am instantiating them using
applicationContext.getBean();
Thanks for any help/suggestion!
Upvotes: 2
Views: 1382
Reputation: 131436
You have two beans that are HomePage
instances : homePage
and webHomePage
.
So Spring doesn't know which homePage
instance you want as you invoke getBean(Class clazz)
in this way ApplicationContext.getBean(HomePage.class)
.
Note that if you invoke ApplicationContext.getBean(WebHomePage.class)
, it would work as you have a single instance of WebHomePage
.
As alternative with the programmatic way to retrieve the bean, you can use ApplicationContext.getBean(String name)
by passing the bean name such as :
HomePage homePage = ApplicationContext.getBean("homePage")
Or :
HomePage homePage = ApplicationContext.getBean("webHomePage")
Please note that I cannot autowire these classes anywhere as there are around 40 of them, which is why I am instantiating them using
I don't really get why you could not use @@utowired
. You should autowire the beans a the place where you need them.
Retrieving 40 beans in one shot will give too much responsibility to your method and to your class.
Upvotes: 0
Reputation: 16053
By Default, Spring framework automatically searches for matching bean. In case you have more than one bean for the same class(which includes the child classes) then you have to use
@Qualifier("beanName")
for matching by bean Name.
In your case, You can do the following:
@Component
@Qualifier("homePage")
public class HomePage extends BasePage {
}
and
@Component
@Qualifier("webHomePage")
public class WebHomePage extends HomePage {
}
Now you can use the following to get the HomePage
bean:
HomePage page = (HomePage)applicationContext.getBean("homePage");
Upvotes: 1