Why do we use qualifiers with @Bean when we can have different names for different beans of the same type (class)?
@Bean
@Qualifier("fooConfig")
public Baz method1() {
}
Isn't the following code more clean?
@Bean("fooConfig")
public Baz method1() {
}
If I create two beans of the same type with different names (using @Bean annotation), then can we inject them specifically using the @Qualifier annotation(can be added on field/constructor parameter/setter) in another bean?
@Bean("fooConfig")
public Baz method1(){
}
@Bean("barConfig")
public Baz method2(){
}
// constructor parameter of a different bean
final @Qualifier("fooConfig") Baz myConfig
If the above is true, then where do we use @Qualifier (with @Bean or @Component) instead of giving the bean a name as shown below?
@Bean
@Qualifier("fooConfig")
public Baz method1(){
}
@Bean
@Qualifier("barConfig")
public Baz method2(){
}
// constructor parameter of a different bean
final @Qualifier("fooConfig") Baz myConfig
CodePudding user response:
- Beans have names. They don't have qualifiers. @Qualifier is annotation, with which you tell Spring the name of Bean to be injected.
- No.
- Default Qualifier is the only implementation of the interface(example is below, 4th question) or the only method with a particular return type. You don't need to specify the @Qualifier in that case. Spring is smart enough to find itself.
For example:
@Configuration
public class MyConfiguration {
@Bean
public MyCustomComponent myComponent() {
return new MyCustomComponent();
}
}
If you will try to inject myComponent somewhere, Spring is smart enough to find the bean above. Becaude there is only one Bean with return type MyCustomComponent. But if there was a couple of methods, that would return MyCustomComponent, then you would have to tell Spring which one to inject with @Qualifier annotation.
SIDENOTE: @Bean annotation by default Spring uses the method name as a bean name. You can also assign other name like @Bean("otherComponent").
- You have one Interface, and a couple of Classes implementing it. You inject bean of your interface. How can Spring know which Class should be used?
This is you interface:
public interface TestRepository{}
This is your implementation 1:
@Repository
public class Test1Repository implements TestRepository{}
Your implementation 2:
@Repository
public class Test2Repository implements TestRepository{}
Now you are injecting it like:
private final TestRepository testRepository;
public TestServiceImpl(TestRepository testRepository) {
this.testRepository= testRepository;
}
QUESTION! How is Spring supposed to know which class to inject? Test1 or Test2? That's why you tell it with @Qualifier which class.
private final TestRepository testRepository;
public TestServiceImpl(@Qualifier("test1Repository") TestRepository testRepository) {
this.testRepository= testRepository;
}
CodePudding user response:
We use the qualifier when we have more than one class implementing the same interface.
interface I{
}
class A implements I{
}
class B implements I{
}
here we have two classes A and B which implements interface I and if we make a bean of interface I then spring will confused and for that we are using qualifier.