Reputation: 1796
Is there any differences between the following 2 bean declaration?
@Bean(name = "bean1")
public A getA() {
return new A();
}
@Bean
@Qualifier("bean1")
public A getA() {
return new A();
}
Both can be autowired using @Qualifier
@Autowire
public void test(@Qualifier("bean1") A a) {
...
}
Upvotes: 38
Views: 36670
Reputation: 1361
Yes there is a difference: @Bean("foo")
(or @Component("foo")
) gives your bean the name "foo" in the Spring Context, whereas @Qualifier("foo")
only adds information without changing the name of the bean.
As the bean name is the bean's unique identifier in the Context, you can only have 1 bean named "foo", whereas you can have multiple beans with @Qualifier("foo")
.
Example:
interface TypeOne {}
The following will add a bean with name "beanOne", automatically generated from the class name.
@Component // explicitly: @Component("beanOne")
class BeanOne implements TypeOne {
}
Same as the following declaration within a @Configuration
class:
@Bean // explicitly: @Bean(name = "beanOne")
BeanOne beanOne() { return new BeanOne(); }
The following will add a bean with name "beanTwo" and another with name "beanThree", with the same qualifier "beanQualifier":
@Component
@Qualifier("beanQualifier")
class BeanTwo implements TypeOne { }
@Component
@Qualifier("beanQualifier")
class BeanThree implements TypeOne { }
With the above, you can autowire using the qualifier:
@Autowired
@Qualifier("beanQualifier")
Map<String, TypeOne> typeOneMap;
The map will only contain the 2 beans with qualifier "beanQualifier".
{beanThree=BeanThree@9f674ac, beanTwo=BeanTwo@1da4b3f9}
The other, "beanOne", has not been wired into the map because it's not qualified by "beanQualifier".
Note that the map keys are the bean names that have been automatically generated.
Upvotes: 21
Reputation: 437
@Qualifier("beanName")
does not guarantee the uniqueness of bean names. For example:
class SomeBean{
// class of some bean;
}
@Configuration
class BeanConfig{
@Bean (name = "beanConfig") // will cause run error, as spring-boot already automatically creates a bean named "beanConfig" due to the @Configuration annotation;
@Qualifier("beanConfig") // can run without error;
SomeBean createBean(){
// return a bean of class SomeBean;
}
}
Thus, using @Bean(name = "beanConfig")
is better to avoid duplicated bean names -- the run error will help us to notice: "ha, the bean should be named as someBean
not beanConfig
".
Upvotes: 3
Reputation: 318
You can have multiple beans with same Qualifier name but bean name in spring application context needs to be unique
@Bean
@Qualifier("qualifier1")
Foo foo()
{
return new Foo();
}
@Bean
@Qualifier("qualifier1")
Bar bar()
{
return new Bar();
}
The above code is acceptable. but in the case of bean, it is not.
Upvotes: 6
Reputation: 793
You can use
@Autowire
public void test(A bean1) {
...
}
if you use
@Bean(name = "bean1")
not with
@Bean
@Qualifier("bean1")
Upvotes: 4
Reputation: 5826
With value()
you don't have to specify attribute name, like @Qualifier("bean1")
. Attribute name()
reference the same value as value()
because of custom annotation @AliasFor(..)
from Spring, therefore they are just different names with the same behavior.
Upvotes: 11
Reputation: 503
The first part is fundamentally the same, the second part is what you basically need when two or more beans of same type exist. The first part is just the preference one might have.
Upvotes: 4