Все еще существует большая путаница по поводу различий типов управляемых bean-компонентов, предоставляемых в Java EE 6 с EJB, CDI-компонентами и JSF-управляемыми bean-компонентами. Эта статья призвана прояснить некоторые различия между ними и определить, когда их использовать.
Некоторые люди предполагают, что для всех этих различных типов бобов есть какой-то смысл, который они просто не понимают. Однако проблема заключается в том, что различные API-интерфейсы перекрываются, что вызывает сожаление.
JSF Managed Beans, CDI Beans и EJB
Изначально JSF был разработан с собственным механизмом управления управляемыми компонентами и компонентами, который был улучшен для JSF 2.0 и теперь включает компоненты на основе аннотаций. Когда CDI был выпущен с Java EE 6, он рассматривался как структура управляемых компонентов для этой платформы, и, конечно, EJB-системы устарели их все уже более десяти лет.
Проблема, конечно, в том, чтобы знать, какой использовать и когда, но все они связаны с одним и тем же процессом. Как правило, класс должен быть идентифицирован как управляемый bean-компонент, и, если необходимо, для использования в JSF потребуются область действия, квалификаторы и имя. Далее следует краткое описание различных типов управляемых bean-компонентов и того, как и когда их использовать.
Давайте начнем с самого простого, JSF Managed bean.
JSF Managed Beans
Короче говоря, не используйте их, если вы разрабатываете для Java EE 6 и используете CDI. Они предоставляют простой механизм для внедрения зависимостей и определения базовых компонентов для веб-страниц, но они гораздо менее мощны, чем компоненты CDI.
Их можно определить с помощью аннотации @ javax.faces.bean.ManagedBean, которая принимает необязательный параметр имени. Это имя может использоваться для ссылки на bean-компонент со страниц JSF.
Область может быть применена к компоненту, используя одну из различных областей, определенных в пакете javax.faces.bean , которые включают запрос, сеанс, приложение, представление и пользовательские области.
@ManagedBean(name="someBean") @RequestScoped public class SomeBean { .... .... }
Бины JSF нельзя смешивать с другими типами бинов без какого-либо ручного кодирования.
CDI Beans
CDI — это структура управления bean-компонентами и внедрения зависимостей, выпущенная как часть Java EE 6, и она включает в себя комплексное комплексное средство управляемых bean-компонентов. Компоненты CDI намного более продвинуты и гибки, чем простые управляемые компоненты JSF. Они могут использовать перехватчики, область разговора, события, безопасное внедрение типа, декораторы, стереотипы и методы производителя.
Для развертывания компонентов CDI необходимо поместить файл с именем beans.xml в папку META-INF на пути к классам. Как только вы это сделаете, каждый компонент в пакете становится компонентом CDI. В CDI есть много функций, их слишком много, чтобы их можно было здесь описать, но в качестве краткого справочника по функциям, подобным JSF, вы можете определить область действия компонента CDI, используя одну из областей, определенных в пакете javax.enterprise.context ( а именно, области запроса, разговора, сеанса и приложения). Если вы хотите использовать компонент CDI со страницы JSF, вы можете дать ему имя, используя аннотацию javax.inject.Named . Чтобы внедрить bean-компонент в другой bean-компонент, вы должны аннотировать поле аннотацией javax.inject.Inject .
@Named("someBean") @RequestScoped public class SomeBean { @Inject private SomeService someService; }
Автоматическое внедрение, как определено выше, может управляться с помощью квалификаторов, которые могут помочь сопоставить определенный класс, который вы хотите ввести. Если у вас есть несколько типов платежей, вы можете добавить квалификатор для того, является ли он асинхронным или нет. В то время как вы можете использовать аннотацию @Named в качестве квалификатора, вы не должны, как это предусмотрено для представления бинов в EL.
CDI обрабатывает инъекцию бобов с несовпадающими областями действия с помощью прокси. Вследствие этого вы можете внедрить bean-объект области действия запроса в bean-объект области действия, и ссылка будет по-прежнему действительна для каждого запроса, поскольку для каждого запроса прокси-сервер повторно подключается к активному экземпляру bean-объекта области действия запроса.
CDI также имеет поддержку перехватчиков, событий, новой области диалога и многих других функций, что делает его намного лучшим выбором по сравнению с управляемыми компонентами JSF.
EJB
EJB предшествуют bean-компонентам CDI и в некотором роде похожи на bean-компоненты CDI, а в других отношениях сильно отличаются. Прежде всего, различия между компонентами CDI и EJB заключаются в том, что EJB:
- транзакционный
- Удаленный или локальный
- Способен пассивировать сохраняющие состояние бины, освобождая ресурсы
- Возможность использовать таймеры
- Может быть асинхронным
Два типа EJB называются без сохранения состояния и с состоянием. EJB без сохранения состояния можно рассматривать как поточно-ориентированные одноразовые компоненты, которые не поддерживают состояния между двумя веб-запросами. Stateful EJB-компоненты действительно хранят состояние и могут создаваться и сидеть без дела столько времени, сколько они необходимы, пока они не будут уничтожены.
Определить EJB просто, вы просто добавляете в класс аннотацию javax.ejb.Stateless или javax.ejb.Stateful .
@Stateless public class BookingService { public String makeReservation(Item Item,Customer customer) { ... ... } }
Бины без сохранения состояния должны иметь зависимую область, в то время как сессионный компонент с состоянием может иметь любую область. По умолчанию они являются транзакционными, но вы можете использовать аннотацию атрибута транзакции.
Хотя EJB-компоненты и компоненты CDI сильно различаются с точки зрения особенностей, написание кода для их интеграции очень схоже, поскольку компоненты EJB могут быть внедрены в EJB-компоненты, а EJB-компоненты могут быть введены в компоненты CDI. Нет необходимости делать какие-либо различия при введении одного в другой. Опять же, различные области действия обрабатываются CDI посредством использования прокси. Единственным исключением является то, что CDI не поддерживает внедрение удаленных EJB-компонентов, но это можно реализовать, написав для него простой метод-производитель.
Javax.inject.Named аннотации, а также любой Отборочные может быть использован на EJB , чтобы соответствовать его к точке впрыска.
Когда использовать какой боб
Как вы знаете, когда использовать какой боб? Просто.
Никогда не используйте управляемые компоненты JSF, если вы не работаете в контейнере сервлетов и не хотите пытаться заставить CDI работать в Tomcat (хотя у меня есть архетип Maven для этого, поэтому нет оправдания).
В общем, вы должны использовать компоненты CDI, если вам не нужны расширенные функциональные возможности, доступные в EJB, такие как транзакционные функции. Вы можете написать свой собственный перехватчик, чтобы сделать бины CDI транзакционными , но пока проще использовать EJB, пока CDI не получит транзакционные бины CDI, которые уже не за горами. Если вы застряли в контейнере сервлета и используете CDI, то единственными вариантами без EJB-компонентов являются либо рукописные транзакции, либо собственный перехватчик транзакций.
С http://www.andygibson.net/blog/article/comparing-jsf-beans-cdi-beans-and-ejbs/