Как внедрить любой bean-компонент, соответствующий квалификатору в CDI - PullRequest
0 голосов
/ 06 августа 2020

Используя CDI в JakartaEE, я хочу внедрить bean-компоненты, соответствующие любому заданным квалификаторам, а не bean-компонентам, которые соответствуют всем квалификаторам:

@MikeD class MikeDBean implements BBoy {}
@AdRock class AdRockBean implements BBoy {}
@MCA class MCABean implements BBoy {}

class Alive {

  @Inject
  @AdRock
  @MCA
  Instance<BBoy> performers;
}

В данном примере CDI не будет внедрять bean-компонент, поскольку нет кандидата, квалифицированного одновременно как MCA, так и AdRock. Как я могу ввести и MCA, и AdRock? Другими словами, как я могу внедрить CDI с использованием квалификаторов OR , а не AND .

Ответы [ 3 ]

0 голосов
/ 10 августа 2020

Отвечая на мой собственный вопрос, поскольку решение Джонатана также действительно.

Я закончил тем, что таким образом ввел зависимости от объявления класса. Сервисы внедряются при инициализации и доступны как итерируемые, что позволяет мне передавать их в потоковом режиме.

abstract class Song {

    Iterable<BBoy> mcs;

    protected void setMCs(BBoy... bboy) {
        this.mcs = Arrays.asList(bboy);
    }
}

class Alive extends Song {
    @Inject
    void init(@MCA BBoy mca, @AdRock BBoy adRock) {
        this.setMCs(mca, adRock);
    }
}
0 голосов
/ 11 августа 2020

Если вы не хотите использовать метод, который я описал в другом ответе, вам нужно написать переносимое расширение CDI (звучит пугающе, но на самом деле это довольно просто). Дело в том, что вы действительно хотите получить , прямо противоположное тому, что говорит спецификация CDI. Что, собственно говоря, хорошо! Вот для чего нужны расширения.

Вы бы сделали любую аннотацию, возможно, @Either({AdRock.class, MCA.class}). Тогда ваше расширение будет реализовывать этот метод:

<T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> pat) {
...
}

И прослушивать классы, аннотированные вашей аннотацией @Either. На этом этапе вы можете изучить введенные поля и определить, что вы хотите сделать.

Ссылки:

Примеры (поиск в случайном порядке):

0 голосов
/ 06 августа 2020

Обычно это делается следующим образом:

  @Inject
  @Any
  Instance<BBoy> performers;

Затем выполняется выбор:

  Instance<BBoy> select = baseControllerInstance.select(new NamedLiteral...);
  ... select.get();

Значение AnnotationLiteral будет примерно таким:

 private class NamedLiteral extends AnnotationLiteral<BBoy> implements AdRock, MCA {}

Каталожные номера:

Пистолеты:

  • Instance <> и Provider <> - непростые мастера. Если вы случайно используете их с зависимыми bean-компонентами с ограниченной областью видимости, вы должны вызвать метод provider.destroy (instance), иначе ваше приложение будет протекать!
...