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

я переношу приложение на Java EE 7 и хотел бы CDI 1.1. Но я не понимаю значения bean-discovery-mode="annotated". Этот спецификация КДИ 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" to bean-discovery-mode="annotated" контейнер не может ввести экземпляр в поле lc.

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

3 ответов


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

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

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

CDI может только управлять и впрыскивать бобы аннотируется типом scope в неявном архиве.

Edit: поэтому, чтобы быть абсолютно ясным, вам нужно добавить тип области в 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


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

обратите внимание, что определение "Bean defining annotation" изменилось в CDI 1.2 и теперь очень хорошо определено:

набор аннотаций определения компонента содержит:

  • @ApplicationScoped, @SessionScoped, @ConversationScoped и @RequestScoped аннотации,
  • все остальные обычные типы областей,
  • @Interceptor и @Decorator аннотации,
  • все аннотации стереотипов (т. е. аннотации, аннотированные @Stereotype), и аннотацию @ Dependent scope.

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

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}

Если вы предоставляете бобы.XML-файл:

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

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

но Wildfly 10 рассматривает класс как компонент CDI и вводит сервис EJB, который не ожидается. Чтобы заставить бобы работать.xml-файл должен выглядеть следующим образом:

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

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