
# @Primary

`@Primary()` makes a bean the one injected when several beans have the requested type.

## Why

When two beans implement the same interface, asking for that interface is ambiguous, and the startup fails with a `NoUniqueBeanDefinitionException`. Mark the usual implementation `@Primary()`. Inject the others with [@Qualifier](qualifier.md) where they are wanted.

Typical cases:

- a default implementation and a specialized one;
- a test that registers a replacement bean marked primary;
- a decorator or composite that wraps the other beans of its type. A bean is never injected into itself, so a `@Primary` composite that asks for `List<Greeter>` receives the other greeters.

When a single dependency has several candidates, the container picks, in this order:

1. the only candidate;
2. the single `@Primary` one (a local `@Primary` beats a parent context's; two `@Primary` candidates are an error);
3. the only one that is not [@Fallback](fallback.md);
4. the one named like the parameter, or the one the `@Qualifier` names.

## Example

```dart
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';
}

@Component()
class FrenchGreeter implements Greeter {
  @override
  String greet(String name) => 'Bonjour $name';
}

// Gets the EnglishGreeter: it is primary.
@Service()
class Welcome {
  Welcome(this.greeter);
  final Greeter greeter;
}
```

`context.getBean<Greeter>()` also returns the `EnglishGreeter`. A `List<Greeter>` still receives both.

A test can override a bean of the application the same way:

```dart
final context = AnnotationConfigApplicationContext([appBeans])
  ..registerBean<Greeter>((_) => FakeGreeter(), name: 'fakeGreeter', primary: true)
  ..refresh();
```

## Parameters

None.

## In Spring (Java)

```java
@Component
@Primary
class EnglishGreeter implements Greeter { ... }
```

The meaning is the same.

## See also

- [@Fallback](fallback.md)
- [@Qualifier](qualifier.md)
- [@Bean](bean.md) (`defaultCandidate`)
- [Jakarta annotations](jakarta.md) (`@Priority`)
- [ApplicationContext](application-context.md)
