Reputation: 4830
I don't understand what problem @Primary
resolves.
The documentation says:
[@Primary] Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.
Example code:
@Configuration
class Configuration {
@Bean
@Primary
MyType bean1() {
return new MyType(1);
}
@Bean
MyType bean2() {
return new MyType(2);
}
}
Example:
I have 2 beans, bean1
and bean2
, both with the type MyType
. bean1
has a @Primary
annotation, so when I autowire an object of type MyType
to some constructor, bean1
will be chosen.
Why is it useful to have two beans of the same type if the primary bean will always be chosen? When and how could I use bean2
which isn't annotated as primary? The example shows that bean2
is redundant and unused.
Upvotes: 17
Views: 21852
Reputation: 44150
You can still always qualify which bean you actually want, meaning the primary one will not always be chosen.
@Component
class MyComponent
{
public MyComponent(@Qualifier("bean2") MyType foo) { /*...*/ }
}
@Primary
just tells Spring which bean to give precedence to if there are two or more possible candidates. You can always be explicit.
Also, another constructor might take a list of all MyType
s. In which case, both beans would be autowired.
@Component
class AnotherComponent
{
public AnotherComponent(List<MyType> allFoos) { /*...*/ }
}
Upvotes: 9
Reputation: 672
One of possible usages of @Primary you can override your Bean in tests by set @Primary there. Still your secondary Bean is used when you run an application.
Upvotes: 0
Reputation: 32145
So why could I have two beans of the same type if primary bean will be injected?
Actually the primary
bean will be only injected if you didn't specify which one of your beans you want to inject, and @Primary
is used to specify which bean will be injected when the type is not specified.
And to answer your question, having two beans of the same type is a common way of giving different implementations, there are many cases when we want to use two beans of the same bean, the most common situation is when we want to specify two data sources for the same application.
And to specify which one of our beans we want to go with, we use the @Resource annotation like this:
@Resource(name="bean2")
MyType bean;
For futher details you can check the discussed differences between @Resource
and @Autowired
.
Upvotes: 3
Reputation: 9786
Say you have multiple instances of beans which have some differences among them. In many cases (say > 90% for example) you will need one of them, and you will rarely use the other ones. In this case it makes sense to annotate as @Primary
the most used one and in this way it will be directly injected by the framework when no further specification is provided. In the other case you will specify the exact bean to use using the @Qualifier
annotation.
An example can be initializing beans of RestTemplate
, say you will define a global one which will have generic settings and will be used accross all application, and another one with some specific retry policy for a small set of use-cases.
Upvotes: 1