@Qualifier
@Qualifier('...') picks one bean among several of the same type, by a label or a bean name.
Why
When several beans share a type, the container needs to know which one to inject. @Primary gives a default. @Qualifier selects a specific one where the default is not wanted.
It has two sides:
- on a bean declaration (a class or a
@Beanmethod) it gives the bean a label; - on an injection point (a constructor parameter, a field, a setter, a
@Beanparameter) it selects the bean with that label, or the bean with that name or alias.
Without any annotation, a parameter named like a bean also selects it: a parameter frenchGreeter gets the bean named frenchGreeter.
Lookups in code take a qualifier too: context.getBean<Greeter>(qualifier: 'fr').
Example
import 'package:spring_core_dart/spring_core_dart.dart';
abstract interface class Greeter {
String greet(String name);
}
@Component()
@Primary()
class EnglishGreeter implements Greeter {
@override
String greet(String name) => 'Hello $name';
}
// Labelled 'fr'.
@Component()
@Qualifier('fr')
class FrenchGreeter implements Greeter {
@override
String greet(String name) => 'Bonjour $name';
}
// This page is French, whatever the default greeter is.
@Service()
class Welcome {
Welcome(@Qualifier('fr') this.greeter);
final Greeter greeter;
}
// A bean name works as a qualifier too.
@Service()
class Banner {
@Autowired()
@Qualifier('englishGreeter')
late final Greeter greeter;
}
Parameters
| Name | Type | Default | Meaning |
|---|---|---|---|
value (positional) |
String |
required | The label, or a bean name or alias. |
In Spring (Java)
@Component
@Qualifier("fr")
class FrenchGreeter implements Greeter { ... }
@Service
class Welcome {
Welcome(@Qualifier("fr") Greeter greeter) { ... }
}
Difference that matters: in Spring, a custom qualifier annotation (an annotation meta-annotated with @Qualifier) matches by its type and attributes. Here annotations are not read at run time, so qualifiers match by their value only.
See also
- @Primary, @Fallback
- @Autowired
- Jakarta annotations (
@Named,@Resource) - @Bean (
defaultCandidate)