Статьи

Сравнение JSF Beans, CDI Beans и EJB

Все еще существует большая путаница по поводу различий типов управляемых 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/