
# @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 `&factory` works too) and have the point's type.
- A nullable point receives `null` when 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 `@Primary` or 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 neither `Ordered` nor `@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

```dart
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)

```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:

- `@Resource` works on fields and setters only. There are no `@Resource` methods with other names, and no `type`, `lookup` or JNDI attributes.
- `Provider`, `Resource` and `Priority` come from a separate library (`jakarta.dart`); `Inject` and `Named` come with the main library.

## See also

- [@Autowired](autowired.md)
- [@Component](component.md)
- [@Qualifier](qualifier.md)
- [@Primary](primary.md)
- [ObjectProvider](object-provider.md)
