Все уже объяснено в javadoc, цитирую:
По сравнению с инъекционным T
непосредственно(неявно с помощью @Inject
только), инъекционный Provider<T>
позволяет:
- извлечение нескольких экземпляров ,
- ленивый или необязательный поиск экземпляра.
- нарушение круговых зависимостей.
- область абстрагирования, чтобы вы могли искать экземпляр в меньшем объеме из экземпляра в области, содержащей область.
Пример # 1:
Здесь вы получите несколько экземпляров Seat
от того же поставщика, так что используется в качестве завода.
class Car {
@Inject
Car(Provider<Seat> seatProvider) {
Seat driver = seatProvider.get();
Seat passenger = seatProvider.get();
...
}
}
Пример # 2:
Здесь вы используете поставщик, чтобы избежать создания непосредственно экземпляра класса MyClassLongToCreate
, как мы знаем, что это медленная операция, поэтому мы получим его лениво спасибо к методу get
только тогда, когда это необходимо.
class MyClass {
@Inject
private Provider<MyClassLongToCreate> lazy;
...
}
Пример # 3:
Вот циклическую зависимость, которая не может быть решена легко контейнера таким образом, что некоторые контейнеры могли просто выбросить исключение, так как они не знают, как решить эту проблему по их собственным.
class C1 {
private final C2 c2;
@Inject
C1(C2 c2) {
this.c2 = c2;
...
}
}
class C2 {
private final C1 c1;
@Inject
C2(C1 c1) {
this.c1 = c1;
...
}
}
Чтобы исправить это, мы используем Provider
, по меньшей мере, одного из конструкторов, чтобы разорвать циклическую зависимость в следующем:
class C1 {
private final Provider<C2> c2;
@Inject
C1(Provider<C2> c2) {
this.c2 = c2;
...
}
}
Это позволит контейнер полностью создать экземпляр C1
первого (так как нам действительно не нужно создавать экземпляр C2
, чтобы ввести поставщика C2
), как только это будет сделано, контейнер сможет создать экземпляр C2
из этого экземпляра C1
.
Пример # 4:
Здесь у вас есть класс C2
, который распространяется до сессии, которая зависит от C1
что itslef контекстного на запрос, мы используем поставщик, чтобы позволить нам получить экземпляр C1
, соответствующий текущему запросу, поскольку он будет меняться с одного запроса на другой.
@RequestScoped
public class C1 {
...
}
@SessionScoped
public class C2 {
@Inject
private Provider<C1> provider;
...
public void doSomething() {
// Get the instance corresponding to the current request
C1 c1 = provider.get();
...
}
}
примеры очень ясно, спасибо Nicolas – diligent
# 2 - медленное это не единственная причина, вы можете также иметь потребность в объекте впрыскивается будет создан, когда на самом деле нужно, а не в начальный момент времени впрыска. –
@ ThorbjørnRavnAndersen, если на # 2 вы имеете в виду «Пример для №2», это всего лишь пример, чтобы показать идею больше ничего. То, что вы описали, уже упоминалось в моем ответе, это «необязательный поиск» –