Я чувствую, что в спецификации Java EE 6 есть небольшой беспорядок. Есть несколько наборов аннотаций.
У нас есть javax.ejb
аннотации вроде @Stateful
и @Stateless
для создания EJB.
Также существует объект @javax.annotation.ManagedBean
для создания управляемого bean-компонента.
Есть аннотации в javax.enterprise.context
лайках @SessionScoped
и @RequestScoped
.
Более того, в пакете также есть аннотации @ManagedBean
и @SessionScoped
/ .@RequestScoped
javax.faces.bean
А чтобы усложнить ситуацию, есть пакет javax.inject
с @Named
аннотацией.
Кто-нибудь может описать, как они связаны друг с другом?
Где я могу использовать @EJB
, @Inject
или @ManagedPropery
вводить другие бобы?
java
jakarta-ee
java-ee-6
cdi
Петр Гвязда
источник
источник
Ответы:
Прежде всего позвольте мне сделать некоторые пояснения:
Определение управляемого компонента : обычно управляемый компонент - это объект, жизненный цикл которого (создание, разрушение и т. Д.) Управляется контейнером.
В Java ee у нас есть много контейнеров, которые управляют жизненным циклом своих объектов, таких как контейнер JSF, контейнер EJB, контейнер CDI, контейнер сервлетов и т. Д.
Все эти контейнеры работают независимо, они загружаются при инициализации сервера приложений и сканируют классы всех артефактов, включая файлы jar, ejb-jar, war и ear, во время развертывания, а также собирают и хранят некоторые метаданные о них, а затем, когда вам нужен объект класса во время выполнения они предоставят вам экземпляры этих классов и после завершения работы уничтожат их.
Итак, мы можем сказать, что у нас есть:
Поэтому, когда вы видите слово Managed Bean, вы должны спросить о контексте или его типе (JSF, CDI, EJB и т. Д.)
Тогда вы можете спросить, почему у нас много таких контейнеров: AFAIK, ребята из Java EE хотели иметь структуру внедрения зависимостей, но они не могли собрать все требования в одной спецификации, потому что они не могли предсказать будущие требования, и они сделали EJB 1.0, а затем 2.0, а затем 3.0 и теперь 3.1, но целью EJB было лишь выполнение некоторых требований (транзакция, модель распределенных компонентов и т. Д.).
В то же время (параллельно) они поняли, что им тоже нужна поддержка JSF, затем они сделали управляемые bean-компоненты JSF и еще один контейнер для JSF-компонентов, и они посчитали его зрелым контейнером DI, но все же это не был законченный и зрелый контейнер.
После этого Гэвин Кинг и еще несколько хороших парней;) сделали CDI, который является наиболее зрелым контейнером DI, который я когда-либо видел. CDI (вдохновленный Seam2, Guice и Spring) был создан, чтобы заполнить пробел между JSF и EJB и множеством других полезных вещей, таких как внедрение pojo, методы производителя, перехватчики, декораторы, интеграционный SPI, очень гибкий и т. Д., И он даже может делать то, что делают управляемые компоненты EJB и JSF, тогда у нас может быть только один зрелый и мощный контейнер DI. Но по какой-то обратной совместимости и по политическим причинам ребята из Java EE хотят сохранить их !!!
Здесь вы можете найти разницу и варианты использования для каждого из этих типов:
Управляемые компоненты JSF, компоненты CDI и EJB
Первоначально JSF был разработан с собственным управляемым bean-компонентом и механизмом внедрения зависимостей, который был расширен в JSF 2.0 для включения bean-компонентов на основе аннотаций. Когда CDI был выпущен вместе с Java EE 6, он считался фреймворком управляемых компонентов для этой платформы и, конечно же, EJB устарели, поскольку существовали уже более десяти лет.
Проблема, конечно, заключается в том, чтобы знать, какой из них использовать и когда их использовать.
Начнем с простейших JSF Managed beans.
Управляемые компоненты JSF
Короче говоря, не используйте их, если вы разрабатываете для Java EE 6 и используете CDI. Они предоставляют простой механизм для внедрения зависимостей и определения компонентов поддержки для веб-страниц, но они намного менее мощны, чем компоненты CDI.
Их можно определить с помощью
@javax.faces.bean.ManagedBean
аннотации, которая принимает необязательный параметр имени. Это имя можно использовать для ссылки на bean-компонент со страниц JSF.Область действия может быть применена к компоненту с использованием одной из различных областей, определенных в
javax.faces.bean
пакете, которые включают запрос, сеанс, приложение, представление и настраиваемые области.Компоненты JSF не могут быть смешаны с другими видами bean-компонентов без какого-либо ручного кодирования.
CDI Beans
CDI - это среда управления компонентами и внедрения зависимостей, которая была выпущена как часть Java EE 6 и включает в себя полную, всеобъемлющую возможность управляемого компонента. Компоненты CDI намного более продвинуты и гибки, чем простые управляемые компоненты JSF. Они могут использовать перехватчики, область диалога, события, безопасное внедрение типов, декораторы, стереотипы и методы производителя.
Чтобы развернуть компоненты CDI, вы должны поместить файл с именем beans.xml в папку META-INF на пути к классам. Как только вы это сделаете, каждый bean-компонент в пакете станет bean-компонентом CDI. В CDI есть много функций, слишком много, чтобы здесь описывать, но в качестве краткого справочника по функциям, подобным JSF, вы можете определить объем компонента CDI, используя одну из областей, определенных в
javax.enterprise.context
пакете (а именно, запрос, диалог , области сеанса и приложения). Если вы хотите использовать bean-компонент CDI со страницы JSF, вы можете дать ему имя с помощьюjavax.inject.Named
аннотации. Чтобы внедрить компонент в другой компонент, вы аннотируете полеjavax.inject.Inject
аннотацией.Автоматическое внедрение, подобное определенному выше, можно контролировать с помощью квалификаторов, которые могут помочь сопоставить конкретный класс, который вы хотите внедрить. Если у вас несколько типов платежей, вы можете добавить квалификатор, указывающий, является ли он асинхронным или нет. Хотя вы можете использовать
@Named
аннотацию в качестве квалификатора, вам не следует этого делать, поскольку она предназначена для раскрытия bean-компонентов в EL.CDI обрабатывает внедрение bean-компонентов с несовпадающими областями видимости с помощью прокси. Из-за этого вы можете внедрить bean-компонент с ограниченным объемом запроса в bean-компонент с ограниченным сеансом, и ссылка будет по-прежнему действительна для каждого запроса, поскольку для каждого запроса прокси-сервер повторно подключается к активному экземпляру bean-компонента с ограниченным объемом запроса.
CDI также поддерживает перехватчики, события, новую область диалога и многие другие функции, что делает его гораздо лучшим выбором по сравнению с управляемыми компонентами JSF.
EJB
EJB-компоненты предшествуют bean-компонентам CDI и в чем-то похожи на компоненты CDI, а в других отношениях сильно отличаются. Прежде всего, разница между компонентами CDI и EJB заключается в том, что EJB:
Два типа EJB-компонентов называются без сохранения состояния и с сохранением состояния. EJB без сохранения состояния можно рассматривать как потокобезопасные одноразовые компоненты, которые не поддерживают какое-либо состояние между двумя веб-запросами. Компоненты EJB с отслеживанием состояния действительно сохраняют состояние и могут быть созданы и сидеть без дела столько времени, сколько они необходимы, пока они не будут удалены.
Определить EJB просто, вы просто добавляете к классу аннотацию
javax.ejb.Stateless
илиjavax.ejb.Stateful
аннотацию.Компоненты без состояния должны иметь зависимую область видимости, в то время как сеансные компоненты с сохранением состояния могут иметь любую область. По умолчанию они транзакционные, но вы можете использовать аннотацию атрибута транзакции.
Хотя компоненты EJB и компоненты CDI очень различаются по функциям, написание кода для их интеграции очень похоже, поскольку компоненты CDI могут быть введены в EJB, а компоненты EJB могут быть введены в компоненты CDI. Нет необходимости делать какие-либо различия, вводя одно в другое. Опять же, CDI обрабатывает различные области с помощью прокси. Единственным исключением из этого правила является то, что CDI не поддерживает внедрение удаленных EJB-компонентов, но это можно реализовать, написав для него простой метод производителя.
javax.inject.Named
Аннотаций, а также любые Отборочные могут быть использованы на EJB , чтобы соответствовать его к точке впрыска.Когда использовать какой фасоль
Как узнать, какой фасоль использовать? Просто.
Никогда не используйте управляемые bean-компоненты JSF, если вы не работаете в контейнере сервлетов и не хотите пытаться заставить CDI работать в Tomcat (хотя для этого есть несколько архетипов Maven, поэтому нет оправдания).
В общем, вам следует использовать компоненты CDI, если вам не нужны расширенные функции, доступные в EJB, такие как транзакционные функции. Вы можете написать свой собственный перехватчик, чтобы сделать компоненты CDI транзакционными, но сейчас проще использовать EJB, пока CDI не получит транзакционные компоненты CDI, которые уже не за горами. Если вы застряли в контейнере сервлетов и используете CDI, тогда либо рукописные транзакции, либо ваш собственный перехватчик транзакций - единственный вариант без EJB.
Если вам нужно использовать
@ViewScoped
в CDI, вы должны@ViewScoped
будет работать в CDI. MyFaces CODI имеет еще более надежную поддержку @ViewScoped@ViewAccessScoped
, это расширение, написанное Apache поверх CDI, просто загрузите его и используйте@ViewAccessScoped
аннотацию вместо@ViewScoped
.@ConversationScoped
и сделайте его долгим. См. Здесь для получения дополнительной информации .Некоторые детали украли отсюда .
источник
@ManagedProperty("#{someBean})"
путь?@Named
и@javax.enterprise.context.RequestScoped
и используйте внедрение CDI с помощью аннотации @Inject. не используйте управляемые bean-компоненты jsf, если вам это не нужно;).Ага, это может сбивать с толку.
Для некоторых ЭУ исторических причин JSF и CDI используют одни и те же аннотации для областей применения, но из разных пакетов.
Как вы, наверное, догадались, они
javax.faces.bean
взяты из спецификации JSF и не имеют отношения к CDI. Не используйте их, если у вас нет для этого веских причин. И никогда не смешивайте их с аннотациями CDI изjavax.ejb
. Это приведет к появлению бесконечных списков ошибок и мелких аномалий.Обычно я рекомендую вам просмотреть несколько первых (или даже больше) страниц превосходной документации по Weld . Это должно помочь вам перейти к Java EE 6.
И не стесняйтесь задавать дополнительные вопросы здесь.
источник
@javax.annotation.ManagedBean
это бесполезно, поскольку CDI рассматривает все классы как управляемые компоненты, я прав?Поскольку конкретных ответов нет
@javax.annotation.ManagedBean
, вот ссылка на ответ на аналогичный вопрос: Поддержка beans (@ManagedBean) или CDI Beans (@Named)? . Спецификацию можно найти на http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/ . Мне кажется, что@javax.annotation.ManagedBean
это должно было быть обобщением@javax.faces.bean.ManagedBean
.Насколько я понял, управляемые компоненты JSF постепенно заменяются на компоненты CDI (может быть, они устарели с JSF 2.3?), Поэтому я думаю, что
@javax.annotation.ManagedBean
сейчас они все больше устаревают.источник
@Named
заменим@ManagedBean
в будущем?@Named
компоненты CDI заменят JSF@ManagedBeans
, например, в stackoverflow.com/questions/4347374/… , BalusC говорит: «Ожидается, что @ManagedBean и его друзья будут устаревшими в соответствии с Java. EE 8. ".