Значение режима обнаружения 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"....
удивительно, что два наиболее распространенных сервера приложений отличаются здесь по поведению.