@Component
@Component() marks a class as a bean: an object the container creates, injects into others and releases at shutdown.
Why
Most objects of an application are declared this way. You do not call the constructor yourself and you do not pass its arguments by hand. The generator finds the annotated class under a directory scanned by @ComponentScan (or @SpringBootApplication), and the container calls the constructor with the beans it asks for.
By default the bean is a singleton: one instance for the whole context, created at startup.
Use @Component() for any class whose role is not better described by @Service, @Repository or @Controller. Those three do exactly the same thing; only the name differs.
You do not need it for:
- a class from another package, which you cannot annotate: use a @Bean method;
- plain data objects (an
Order, a DTO), which your code creates withnewvalues each time.
Rules:
- The bean name is the class name in lowerCamelCase:
AuthServicebecomesauthService. A name that starts with two capitals stays as it is:URLServicestaysURLService. - An explicit name must not be empty, blank or padded with spaces.
- Only classes can be beans. On a mixin, enum, extension or extension type the build fails.
- The scan skips abstract classes (except those with @Lookup methods).
- A bean is registered under its own type and all its public supertypes, so it can be injected by any of them.
Example
import 'package:spring_core_dart/spring_core_dart.dart';
// A bean with the default name `clock`.
@Component()
class Clock {
DateTime now() => DateTime.now();
}
// Named explicitly because other code looks it up by the name
// 'auditLog'. The container passes the Clock bean to the constructor.
@Component('auditLog')
class AuditLog {
AuditLog(this.clock);
final Clock clock;
String stamp(String message) => '${clock.now().toIso8601String()} $message';
}
Your own stereotype: subclass Component, and the scan treats your annotation like @Component().
// A name that says what the class is for.
class UseCase extends Component {
const UseCase([super.name]);
}
@UseCase()
class PlaceOrder {
PlaceOrder(this.audit);
final AuditLog audit;
}
Parameters
| Name | Type | Default | Meaning |
|---|---|---|---|
name (positional) |
String? |
null |
The bean name. null gives the class name in lowerCamelCase. |
In Spring (Java)
@Component
class Clock { ... }
@Component("auditLog")
class AuditLog {
AuditLog(Clock clock) { ... }
}
Differences that matter:
- Spring finds
@Componentclasses by scanning the classpath at startup. Here the generator scans the source files at build time. Runbuild_runnerafter you add or change annotations. - Spring uses meta-annotations for custom stereotypes. In Dart you subclass
Component. - Two unconditional beans with the same name fail the build, not the startup.