@Inject, @Named, @Resource, @Priority
These are the standard Java (JSR-330 and JSR-250, now Jakarta) injection names, for code that prefers them to the Spring ones.
Why
Code ported from Java often uses @Inject and @Named instead of @Autowired and @Component. These names let it read the same in Dart. Each one maps to a Spring-style feature:
| Name | Same as | Where it lives |
|---|---|---|
@Inject() |
@Autowired() |
spring_core_dart.dart |
@Named('x') on a class |
@Component('x') |
spring_core_dart.dart |
@Named('x') on an injection point |
@Qualifier('x') |
spring_core_dart.dart |
@Resource(name: 'x') |
injection by bean name | jakarta.dart |
@Priority(n) |
ranking among beans of one type | jakarta.dart |
Provider<T> |
ObjectProvider<T> (subset) |
jakarta.dart |
Provider, Resource and Priority are in package:spring_core_dart/jakarta.dart, which spring_core_dart.dart does not export. Their names clash: Provider with package:provider, Resource with this package's own Resource type. Import the library with a prefix where a name clashes.
If you write new code and do not need to match Java sources, the Spring names are enough.
@Inject
Behaves like @Autowired() (with required: true): on a field, a setter, a method or a constructor.
@Named
On a class it declares a bean, like @Component. On an injection point it selects a bean, like @Qualifier.
@Resource
Injects a field or setter by bean name, where @Autowired chooses by type. It helps when many beans share a type.
- Without
name, the field or setter name is the bean name. When no bean has that name, the point is injected by type, like@Autowired. - With
name, that bean must exist (an alias or&factoryworks too) and have the point's type. - A nullable point receives
nullwhen the bean is missing.
@Priority
Ranks a bean among others of the same type, on a bean class or a @Bean method. It does two jobs:
- among several candidates without a
@Primaryor a name match, the one with the lowest value wins (two with the same lowest value are ambiguous); - it orders beans in a
List<T>and listeners, when they have neitherOrderednor@Order.
Provider
A Provider<T> injection point gets the same handle as ObjectProvider<T>. Each get() looks the bean up again. Use it for a bean needed fresh on every use, or to break a cycle.
Example
import 'package:spring_core_dart/spring_core_dart.dart';
import 'package:spring_core_dart/jakarta.dart' as jakarta;
abstract interface class Store {
void put(String key, String value);
}
// Two stores; the fast one ranks first.
@Named('fastStore')
@jakarta.Priority(1)
class FastStore implements Store {
@override
void put(String key, String value) {}
}
@Named('archiveStore')
@jakarta.Priority(5)
class ArchiveStore implements Store {
@override
void put(String key, String value) {}
}
@Named()
class Clock {
DateTime now() => DateTime.now();
}
@Named()
class Reports {
// Constructor parameter selected by name.
Reports(@Named('archiveStore') this.archive, this.clock);
final Store archive;
// Looked up on every get().
final jakarta.Provider<Clock> clock;
// Store wins by @Priority: the FastStore.
@Inject()
late final Store store;
// Exactly the bean named 'archiveStore'.
@jakarta.Resource(name: 'archiveStore')
late final Store backup;
String stamp() => clock.get().now().toIso8601String();
}
Parameters
| Annotation | Name | Type | Default | Meaning |
|---|---|---|---|---|
Inject |
none | |||
Named |
name (positional) |
String? |
null |
The bean name (on a class) or the qualifier (on an injection point). |
Resource |
name |
String? |
null |
The bean name. null uses the field or setter name, with a fallback to injection by type. |
Priority |
value (positional) |
int |
required | The priority. Lower values win and sort first. |
Provider<T> has one method: T get(). It throws NoSuchBeanDefinitionException when no bean matches and NoUniqueBeanDefinitionException when several match and none wins.
In Spring (Java)
@Named("fastStore")
@Priority(1)
class FastStore implements Store { ... }
@Named
class Reports {
@Inject
Reports(@Named("archiveStore") Store archive, Provider<Clock> clock) { ... }
@Inject Store store;
@Resource(name = "archiveStore") Store backup;
}
Differences that matter:
@Resourceworks on fields and setters only. There are no@Resourcemethods with other names, and notype,lookupor JNDI attributes.Provider,ResourceandPrioritycome from a separate library (jakarta.dart);InjectandNamedcome with the main library.