Является ли @javax.annotation.ManagedBean компонентом CDI, определяющим аннотацию?
Вопрос
Учитывая, что архив, который мы развертываем, является "архивом неявных бинов" (см. Ниже), используя @javax.inject.Inject
ввести @javax.annotation.ManagedBean
в другой управляемый компонент в WildFly 8.1.0, но он не будет работать ни в GlassFish 4.0.1-b08, ни в GlassFish 4.1-b13. Сбой GlassFish с этим сообщением:
WELD-001408: Неудовлетворенные зависимости для типа...
Я неправильно понимаю следующие изложенные спецификации или в GlassFish есть ошибка?
CDI 1.1, часть 1
Раздел 12.1 CDI 1.1 ( JSR-346) "Архив бобов" гласит:
Явный архив bean-компонентов - это архив, содержащий файл beans.xml [..]. Неявный архив бинов - это любой другой архив, который содержит один или несколько классов бинов с аннотацией, определяющей бин [..].
Если тогда мой архив не имеет beans.xml
Файл дескриптора, я все еще буду в состоянии использовать bean-компоненты, которые имеют "аннотацию, определяющую bean-компонент". Вопрос в том, что такое аннотация, определяющая компонент?
Раздел 2.5 спецификации CDI "Аннотации, определяющие компоненты" говорит:
Любой тип области действия является аннотацией, определяющей компонент.
Так что это довольно ясно, и это все, что нужно сделать в соответствии с этим разделом спецификации CDI. Если я разверну архив без beans.xml
файл дескриптора в нем, тогда я могу @Inject бины, если они имеют явно объявленную область видимости, @javax.enterprise.context.RequestScoped
например. Работает как в WildFly, так и в GlassFish. Тем не мение..
Управляемые бобы
Спецификация подмножества, которой должны соответствовать все спецификации в стеке технологий Java EE, ManagedBeans ( JSR-316), имеет "базовую модель", в которой @javax.annotation.ManagedBean
определить управляемый бин. Спецификация управляемых бинов не говорит, что @ManagedBean
делает боб вероятной целью инъекции для точки инъекции (т. е. поля или параметра). В спецификации сказано, что bean-компоненты "могут использоваться в любом месте приложения Java EE" (раздел MB.1.2 "Почему управляемые bean-компоненты?"), Которые в моих ушах звучат так, как будто их тоже можно вводить.
Спецификация Java EE 7 Umbrella
В спецификации Java EE 7 ( JSR-342) сказано в разделе EE.5.24 "Поддержка внедрения зависимостей":
Контейнеры должны поддерживать точки инъекции, аннотированные аннотацией javax.inject.Inject, только в той степени, в какой это диктуется CDI. Согласно спецификации CDI, внедрение зависимостей поддерживается в управляемых bean-компонентах.
В настоящее время у класса есть три способа стать управляемым компонентом:
- Будучи компонентом EJB-компонента сеанса.
- Быть аннотированным аннотацией ManagedBean.
- Удовлетворяет условиям, описанным в спецификации CDI.
Классы, которые удовлетворяют хотя бы одному из этих условий, будут иметь право на полную поддержку внедрения зависимостей, как описано в спецификации CDI.
Вот и все: @ManagedBean имеет "полную поддержку внедрения зависимостей". Не половина или просто немного поддержки. Тем не менее, я не совсем уверен, что такое "поддержка внедрения зависимостей". Но я думаю, что следующий параграф описывает это достаточно хорошо:
Классы компонентов, перечисленные в таблице EE.5-1, которые удовлетворяют третьему условию, описанному выше, но не являются ни первым, ни вторым условием, также могут использоваться в качестве управляемых компонентов CDI, если они аннотированы с помощью определяющей компонент CDI аннотации или содержатся в компоненте архив, для которого включен CDI. Однако, если они используются в качестве управляемых компонентов CDI (например, внедрены в другие управляемые классы), экземпляры, управляемые CDI, могут не быть экземплярами, которые управляются контейнером Java EE.
По сути, этот абзац говорит о том, что вторым условием являются управляемые bean-компоненты CDI, которые могут быть внедрены в другие управляемые классы (потому что bean-компоненты исключений "также могут").
Спецификация зонтика и спецификация управляемых компонентов прояснили, что в спецификации CDI есть последнее слово.
CDI 1.1, часть 2
@ManagedBean
аннотации встречаются в спецификации CDI только два раза, оба они встречаются в главе 11, в которой говорится о событиях CDI жизненного цикла, которые может наблюдать расширение CDI. Раздел 11.5.7 является одним из совпадений и определяет ProcessInjectionPoint
событие. Управляемый компонент может использовать внедрение зависимостей - не удивительно. Тем не менее, раздел 11.5.8 определяет ProcessInjectionTarget
событие. Вот что спецификация должна сказать о событии ProcessInjectionTarget:
Контейнер должен инициировать событие для каждого класса компонента Java EE, поддерживающего внедрение, которое может быть создано контейнером во время выполнения, включая каждый управляемый компонент, объявленный с использованием @ManagedBean, сеанс EJB или управляемый сообщениями компонент, компонент, компонент-перехватчик или декоратор.
Эта фраза, несомненно, говорит о том, что @ManagedBean
может использоваться в качестве цели для точки внедрения без добавления понятия типов области ( @Dependent всегда по умолчанию).
Как указывалось ранее, внедрение @ManagedBean из неявного архива bean работает в WildFly, и, насколько я понимаю, это требуется для всех приведенных выше спецификаций Java EE. Так что я думаю, что в GlassFish есть ошибка. Но спецификация CDI никогда не говорила ни слова о @ManagedBean в разделе 2.5 "Аннотации, определяющие bean-компоненты", и, как всегда, я нервничаю, когда читаю перекрывающиеся спецификации Java EE, поэтому я подумал, что мне следует спросить, прежде чем пойти и подать a " критическая ошибка в команде GlassFish.
РЕДАКТИРОВАТЬ 2014-08-22
Подана ошибка GlassFish: https://java.net/jira/browse/GLASSFISH-21169.
1 ответ
Это не полный ответ, так как путаница неизбежно возникнет, когда мы попытаемся собрать воедино и разобраться во всех спецификациях. Я просто хотел сказать, что CDI 1.2 разъяснил, что именно представляет собой аннотация, определяющая компонент (см. Раздел "2.5.1. Аннотации, определяющие компонент"). CDI 1.2 дать список:
Набор аннотаций, определяющих компоненты, содержит:
- Аннотации @ApplicationScoped, @SessionScoped, @ConversationScoped и @RequestScoped,
- все остальные нормальные типы областей,
- Аннотации @Interceptor и @Decorator,
- все аннотации стереотипа (т.е. аннотации, помеченные @Stereotype),
- и аннотация области видимости @Dependent.
Следует добавить, что то, что определяет "нормальный тип области" (вторая точка маркера), представляет собой пользовательскую область, аннотированную @NormalScope.