So, if I understood correctly, both are the way to determine which bean to autowire if there are multiple candidates. So what exactly is the difference?
Read @Primary as the "default".
If a bean has @Autowired
without any @Qualifier
, and multiple beans of the type exist, the candidate bean marked @Primary
will be chosen, i.e. it is the default selection when no other information is available, i.e. when @Qualifier
is missing.
A good use case is that initially you only had one bean of the type, so none of the code used @Qualifier
. When you then add another bean, you then also add @Qualifier
to both the old and the new bean, so any @Autowired
can choose which one it wants. By also adding @Primary
to the old original bean, you don't have to add @Qualifier
to all the existing @Autowired
. They are "grandfathered" in, so to speak.
@Primary
is also good if e.g. 95% of @Autowired
wants a particular bean. That way, only the @Autowired
that wants the other bean(s) need to specify @Qualifier
. That way, you have primary beans that all autowired wants, and @Qualifier
is only used to request an "alternate" bean.
@Qualifier
should be used in conjuction with @Autowired
always. This will indicate the bean name which needs to be Autowired in case of multiple beans with same type is present in the application context.(so that spring can autowire by name.)
@Primary
should be used in conjuction with @Bean
/ @Autowired
which indicates which bean should be given higher preference, when there are multiple beans of same type is present.
One of the classic use cases where you would use @Primary
is when the framework(example spring-data) expects a bean of some type (example EntityManager) but you have multiple datasources and you would have configured multiple Entity Managers. In such cases @Qualifier
doesn't quite help.
@Qualifier
If there are more than one instances available for an injection point then we can use @Qualifier
annotation to resolve an ambiguity. As @Qualifier
is used at the injection point, there might be two situations where we don't want to or cannot use @Qualifier
.
Autowire.BY_TYPE
. Then, of course, we cannot use @Qualifier
because we actually don't have user-defined injection point specified as @Autowired
or @Inject
The solution to above problems is to use @Primary
annotation.
@Primary
This Indicates that a particular bean should be given preference when multiple beans are candidates to be autowired to a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.