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