@Autowired
@Autowired() asks the container to inject beans into a field, a setter or a method, or chooses which constructor to call.
Why
Constructor parameters of a bean are injected without any annotation. That is the usual way and needs no @Autowired. Use the annotation in these cases:
- on a field or setter: to assign it after construction. Fields must be public and settable (
late finalor non-final). Private fields cannot be injected this way, because the generated code lives in another library; inject them through a constructor parameter (this._repo). - on a method: to call it after construction with injected arguments.
- on a constructor: to choose it when the class has several. Several constructors may be
@Autowired(required: false); the container uses the one with the most parameters whose beans exist.
What an injection point can receive:
- a single bean of its type;
List<T>,Set<T>orMap<String, T>: every bean ofT. Only aListis sorted (byOrdered,@Order,@Priority);ObjectProvider<T>: a handle that looks the bean up later;- the container's own objects:
BeanFactory,ApplicationContext,ApplicationEventPublisher,ResourceLoader,Environment.
A nullable type makes a dependency optional: it receives null when there is no bean. required: false only matters on constructors; on fields, setters and methods it fails the build.
Example
import 'package:spring_core_dart/spring_core_dart.dart';
abstract interface class PaymentGateway {
void charge(double amount);
}
abstract interface class DiscountRule {
double apply(double total);
}
abstract interface class Clock {
DateTime now();
}
class AuditLog {}
@Service()
class Checkout {
// A field, set after the constructor ran.
@Autowired()
late final PaymentGateway gateway;
// Every DiscountRule bean, sorted by @Order.
@Autowired()
late final List<DiscountRule> rules;
// Optional: null when no AuditLog bean exists.
@Autowired()
AuditLog? audit;
// A method, called once with injected arguments.
@Autowired()
void init(Clock clock) => startedAt = clock.now();
DateTime? startedAt;
void pay(double total) {
var amount = total;
for (final rule in rules) {
amount = rule.apply(amount);
}
gateway.charge(amount);
}
}
// Two constructors: the container calls the one with the most
// parameters it can satisfy.
@Service()
class Notifier {
@Autowired(required: false)
Notifier() : clock = null;
@Autowired(required: false)
Notifier.withClock(Clock this.clock);
final Clock? clock;
}
Parameters
| Name | Type | Default | Meaning |
|---|---|---|---|
required |
bool |
true |
On a constructor, false makes it one of several candidates. Elsewhere, use a nullable type instead. |
In Spring (Java)
@Service
class Checkout {
@Autowired PaymentGateway gateway;
@Autowired List<DiscountRule> rules;
@Autowired
void init(Clock clock) { startedAt = clock.now(); }
}
Differences that matter:
- Spring injects private fields by reflection. Here only public fields and setters can be injected.
required = falseon a field or method is Spring's way to make it optional. Here a nullable type does that.refresh()checks every injection point before any bean is created. A missing or ambiguous bean fails the startup with anUnsatisfiedDependencyExceptionthat names the bean and the injection point.
See also
- @Qualifier, @Primary
- @Lazy
- ObjectProvider
- Jakarta annotations (
@Inject,@Resource) - @Value
- @Configurable