Какова цель аннотации CDI @Produces на поле? - PullRequest
0 голосов
/ 30 января 2020

Мне кажется, я понимаю назначение CDI @Produces в сочетании с фабричным методом:

@Produces
public TimeLogger getTimeLogger() {
    return new TimeLogger(new SimpleDateFormat("HH:mm"), Calendar.getInstance());
}

Однако я не совсем понимаю, как следующее может быть полезным эквивалентом:

@Produces
TimeLogger timeLogger;

Поскольку timeLogger будет нулевым во втором случае, то как это будет служить какой-либо цели? Как можно указать на какую-то фабрику, которая может предоставить экземпляр TimeLogger? Нужно ли добавлять классификаторы?

Ответы [ 2 ]

1 голос
/ 31 января 2020

ОК, давайте попробуем еще раз.

Предположим, у меня есть поле в управляемом бине. Он набирается с помощью Foo:

private Foo foo;

Предположим, я установил это поле в методе где-нибудь, используя обычные Java вещи:

// Let's pretend this is called from our constructor.
private void initialize() {
  this.foo = goGetAFooFromLDAPOrSomething();
  // yay, now foo is set to something that I went and got from somewhere;
  // I just went out and got it; I didn't do anything fancy involving
  // CDI
}

Предположим, что в другом месте моего приложения я хочу использовать Foo, но я действительно не хочу снова go преодолевать эту головную боль, и просто хочу указать, что Foo является одним из моих требований, поэтому, будучи хорошим гражданином CDI, я ' d просто как @Inject a Foo:

// In some other class somewhere.
// Hey, CDI, get me a Foo that was produced elsewhere,
// however you do it.
@Inject
private Foo injectedFoo;

Если мы остановимся прямо здесь, эта точка впрыска не будет удовлетворена. В настоящее время никто не «делает» Foo таким образом, чтобы CDI когда-либо знал об этом.

Я могу удовлетворить точку внедрения, просто добавив @Produces в поле foo управляемого компонента. :

@Produces
private Foo foo;

В конце концов, мы сами заполнили это поле, а затем указали CDI, что он может «сделать» Foo, просто возвращая значение этого поля, когда кто-то вызывает Foo для быть введенным куда-нибудь.

Имеет ли это смысл?

Квалификаторы в этом случае ничем не отличаются от других: они являются другим способом указать, какой тип Foo сделан или впрыскивается. Если бы я хотел ввести @Yellow Foo, то я бы обозначил свое желание следующим образом:

@Inject
@Yellow
private Foo injectedFoo;

... и тогда мне нужно было бы убедиться, что что-то где-то производит @Yellow Foo. В этом глупом примере это можно настроить так:

@Produces
@Yellow
private Foo foo;
0 голосов
/ 30 января 2020

Цель состоит в том, чтобы связать внедрение зависимостей CDI, возможно, с другим механизмом внедрения зависимостей, таким как Java EE's @Resource инъекция.

В общем, установка @Produces на поле означает, что когда кто-то еще вызывает объект типа поля, то этот объект будет «создан» содержимым этого поля, каким бы оно ни было, и независимо от того, каким образом оно появилось таким образом.

...