Значение режима обнаружения компонентов, аннотированное в CDI 1.1

Я переношу приложение на Java EE 7 и хочу использовать CDI 1.1. Но я не понимаю смысла bean-discovery-mode="annotated". спецификация CDI 1.1 не очень полезна. По крайней мере, я не нашел ни одного полезного абзаца. Я пропустил это?

Этот пример отлично работает с bean-discovery-mode="all" и внедряет экземпляр LoggingClass:

public class LoggingClass {
    public Logger logger = Logger.getLogger("ALOGGER");

}

@Test
public class MMLoggerProducerIT extends Arquillian {

    @Inject private LoggingClass lc;

}

Но если я перейду с bean-discovery-mode="all" на bean-discovery-mode="annotated", контейнер не сможет внедрить экземпляр в поле lc.

Как я должен аннотировать LoggingClass, чтобы правильно использовать bean-discovery-mode="annotated"?


person Oliver    schedule 19.08.2013    source источник
comment
Я только предполагаю, но я думаю, что «@Named» или «@ManagedBean» были бы кандидатами?   -  person Mike Braun    schedule 19.08.2013
comment
@Mike_Braun Named будет отображать bean-компонент только в контексте EL, но не будет предоставлять ему область действия. ManagedBean — это аннотация JSF, механизм CDI будет ее игнорировать.   -  person Yuri    schedule 28.11.2013


Ответы (3)


На практике bean-discovery-mode="ALL" включает сканирование всех классов в архиве. Это называется «явным архивом».

Отсутствие beans.xml или установка bean-discovery-mode="ANNOTATED" делает архив неявным архивом. В этом случае контейнер будет сканировать bean-компоненты с аннотированными типами областей.

Это объясняет, почему LoggingClass не вводится, когда вы устанавливаете bean-discovery-mode="ANNOTATED". Как описано в учебнике по Java EE 7:

CDI может управлять и внедрять bean-компоненты, аннотированные с типом области действия, только в неявном архиве.

Изменить: так что, чтобы быть абсолютно ясным, вам нужно добавить тип области действия к LoggingClass. Что-то вроде этого:

@SessionScoped
public class LoggingClass {
    public Logger logger = Logger.getLogger("ALOGGER");
}

В Java EE 7 и CDI 1.1 мы удалили требование включать дескриптор развертывания beans.xml для включения CDI для архива, что привело CDI 1.1 в соответствие с большинством других API-интерфейсов Java EE, где дескрипторы развертывания являются необязательными. Он также удалил двоичную природу включения / выключения включения beans.xml или нет. Вы можете контролировать, какие файлы сканируются контейнером, с помощью настроек в bean-discovery-mode.

См. учебник JavaEE по упаковке приложений CDI здесь: http://docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm#CACDCFDE

person Ian Evans    schedule 19.08.2013
comment
Если нет beans.xml, как регистрируются и заказываются перехватчики и декораторы? Есть ли способ? - person noinstance; 25.10.2013
comment
Перехватчики @nosuchnick можно заказать с помощью аннотаций, используя @Interceptors и @Priority, как описано в разделе 54.2.5 здесь. - person Ian Evans; 25.10.2013
comment
он описывает, как заставить @Produces работать? Есть ли аннотация, которую я должен добавить в класс Factory? - person Archimedes Trajano; 04.12.2013

При использовании bean-discovery-mode="annotated" только классов с аннотацией, определяющей компонент обнаружены. Все остальные классы игнорируются. Любой тип области видимости — это аннотация, определяющая компонент. Если тип области действия объявлен в классе компонента, то говорят, что класс компонента имеет аннотацию, определяющую компонент [spec]. Спецификация 1.1 здесь не совсем ясна. Обнаружены только классы с областью видимости @NormalScope или псевдообластью @Dependent, @javax.inject.Singleton и все остальные области видимости @Scope (псевдо) игнорируются .

Обратите внимание, что определение «аннотации, определяющей компонент» изменилось в CDI 1.2 и теперь очень хорошо определено:

Набор аннотаций, определяющих компонент, содержит:

  • Аннотации @ApplicationScoped, @SessionScoped, @ConversationScoped и @RequestScoped,
  • все другие обычные типы прицелов,
  • аннотации @Interceptor и @Decorator,
  • все аннотации стереотипов (т. е. аннотации, аннотированные с помощью @Stereotype) и аннотации области @Dependent.
person rmuller    schedule 20.03.2015

Я также согласен с формой ответа @rmuller. Но я хочу отметить, что на серверах приложений Payara и Wildfly все же наблюдается разное поведение. См. следующий пример с обычным классом без области видимости, но с инъекцией @EJB:

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}

Если вы предоставляете файл beans.xml с:

 .... version="1.2" bean-discovery-mode="annotated"....

Payara 4.1 будет рассматривать класс SomeClass НЕ как компонент CDI и НЕ будет внедрять сервисный EJB. Мне ясно, что он ведет себя так, как заявлено в спецификации.

Но Wildfly 10 рассматривает класс как компонент CDI и внедряет сервисный EJB, который не ожидается. Чтобы это работало, файл beans.xml должен выглядеть так:

 .... version="1.2" bean-discovery-mode="all"....

Удивительно, что два наиболее распространенных сервера приложений отличаются здесь своим поведением.

person Ralph    schedule 14.03.2018