Java EE 6 @javax.аннотация.ManagedBean против @javax.впрыскивать.Названный против @javax.сталкиваться.ManagedBean


я чувствую, что в спецификации Java EE 6 есть небольшой беспорядок. Существует несколько наборов аннотаций.

у нас есть javax.ejb аннотации как @Stateful и @Stateless для создания EJBs.

есть еще и @javax.annotation.ManagedBean для создания управляемого компонента.

есть в аннотации javax.enterprise.context как @SessionScoped и @RequestScoped.

что еще есть также @ManagedBean и @SessionScoped/@RequestScoped аннотации javax.faces.bean пакета.

и сделать вещи события сложнее есть пакет javax.inject С @Named Примечание.

может кто-нибудь описать, как они связаны друг с другом?

где я могу использовать @EJB,@Inject или @ManagedPropery чтобы ввести другие бобы?

3 101

3 ответа:

прежде всего, позвольте мне сделать некоторые уточнения:

определение управляемого компонента : как правило, управляемый боб-это объект, жизненный цикл которого (строительство, разрушение и т. д.) управляется контейнером.

в Java ee у нас есть много контейнеров, которые управляют жизненным циклом своих объектов, таких как контейнер JSF, контейнер EJB, контейнер CDI, контейнер сервлетов и т. д.

все эти контейнеры работают независимо, они загружаются инициализация сервера приложений и сканирование классов всех артефактов, включая файлы jar, ejb-jar, war и ear во время развертывания, а также сбор и хранение некоторых метаданных о них, затем, когда вам нужен объект класса во время выполнения, они дадут вам экземпляры этих классов и после завершения задания они уничтожат их.

Итак, мы можем сказать, что у нас есть:

  • JSF управляемые бобы
  • CDI управляемые бобы
  • управляемый EJB бобы
  • и даже сервлеты являются управляемыми бобами, потому что они создаются и уничтожаются контейнером, который является контейнером сервлетов.

поэтому, когда вы видите управляемое слово Bean, вы должны спросить о контексте или типе его.(JSF, CDI, EJB и др.)

тогда вы можете спросить, почему у нас есть многие из этих контейнеров: AFAIK, Java EE ребята хотели иметь структуру инъекции зависимостей, но они не могли собрать все требования в одной спецификации потому что они не могли предсказать будущие требования, и они сделали EJB 1.0, а затем 2.0, а затем 3.0 и теперь 3.1, но цель EJB была только для некоторых требований (транзакция, распределенная компонентная модель и т. д.).

в то же время (параллельно) они поняли, что им тоже нужно поддерживать JSF, тогда они сделали JSF управляемые бобы и другой контейнер для бобов JSF, и они считали его зрелым контейнером DI, но все же он не был полным и зрелым контейнер.

после этого Гэвин Кинг и некоторые другие хорошие парни ;) сделал CDI, который является самым зрелым контейнером DI, который я видел. CDI (вдохновленный Seam2, Guice и Spring) был сделан, чтобы заполнить пробел между JSF и EJB и множеством других полезных вещей, таких как инъекция pojo, методы производителя, перехватчики, декораторы, интеграция SPI, очень гибкая и т. д. и он может даже делать то, что делают управляемые бобы EJB и JSF, тогда у нас может быть только один зрелый и мощный контейнер DI. Но для некоторых обратная совместимость и политические причины Java EE ребята хотят сохранить их!!!

здесь вы можете найти различие и варианты использования для каждого из этих типов:

управляемых компонентов JSF, КДИ фасоли и компоненты EJB

JSF был первоначально разработан со своим собственным управляемым Бобом и механизмом инъекции зависимостей, который был улучшен для JSF 2.0, чтобы включить аннотации на основе бобов. Когда CDI был выпущен с Java EE 6, он рассматривался как управляемый компонент рамки для этой платформы и, конечно же, EJBs устарели все они были вокруг в течение более десяти лет.

проблема, конечно, зная, какой из них использовать и когда использовать их.

давайте начнем с самых простых, управляемых JSF бобов.

JSF управляемые бобы

короче говоря, не используйте их, если вы разрабатываете для Java EE 6 и используете CDI. Они обеспечивают простой механизм для инъекции зависимостей и определения поддержки бобы для веб-страниц, но они гораздо менее мощные, чем бобы CDI.

они могут быть определены с помощью @javax.faces.bean.ManagedBean аннотации, которая принимает необязательный параметр name. Это имя может использоваться для ссылки на компонент со страниц JSF.

область может быть применена к компоненту, используя одну из различных областей, определенных в javax.faces.bean пакет, который включает запрос, сеанс, приложение, представление и пользовательские области.

@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
    ....
    ....
}

в JSF бобы не могут быть смешаны с другими виды бобов, без какого-либо ручного кодирования.

CDI бобы

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 Примечание. Чтобы ввести боб в другой боб, вы аннотируете поле с помощью javax.inject.Inject Примечание.

@Named("someBean")
@RequestScoped
public class SomeBean {

    @Inject
    private SomeService someService;
}

автоматическая инъекция, как это определено выше, может управляться с помощью квалификаторов, которые могут помочь соответствовать определенному классу, который вы хотите ввести. Если у вас есть несколько типов платежей, вы можете добавить квалификатор для того, является ли он асинхронным или нет. В то время как вы можете использовать @Named аннотация как квалификатор, вы не должны, так как это предусмотрено для разоблачения бобов в EL.

CDI обрабатывает инъекции бобов с несогласованными областями с помощью прокси-серверов. Из-за этого вы можете ввести компонент с областью запроса в компонент с областью сеанса, и ссылка будет по-прежнему действительна для каждого запроса, потому что для каждого запроса прокси-сервер повторно подключается к живому экземпляру компонента с областью запроса.

CDI также имеет поддержку для перехватчиков, событий, нового объема беседы и много другие функции, которые делают его гораздо лучшим выбором по сравнению с управляемыми бобами JSF.

EJB

EJBs предшествуют бобам CDI и в чем-то похожи на бобы CDI и другими способами очень разные. В первую очередь, различия между КДИ фасоли и EJB-компонентов заключается в том, что компоненты EJB являются :

  • транзакционные
  • удаленный или локальный
  • возможность пассивировать статические бобы, освобождая ресурсы
  • возможность использовать таймеры
  • может быть асинхронным

два типа EJBs называются без состояния и с сохранением состояния. Ejbs без состояния можно рассматривать как потокобезопасные одноразовые компоненты, которые не поддерживают состояние между двумя веб-запросами. Stateful EJBs действительно удерживают состояние и могут быть созданы и сидеть до тех пор, пока они не будут утилизированы.

определение EJB просто, вы просто добавляете либо a javax.ejb.Stateless или javax.ejb.Stateful аннотация к класс.

@Stateless
public class BookingService {

  public String makeReservation(Item Item, Customer customer) {
    ...
    ...
  }
}

компоненты без состояния должны иметь зависимую область, в то время как компонент сеанса с отслеживанием состояния может иметь любую область. По умолчанию они являются транзакционными, но вы можете использовать аннотацию атрибута транзакции.

в то время как ejbs и CDI бобы очень разные с точки зрения функций, написание кода для их интеграции очень похоже, так как CDI бобы могут быть введены в EJBs и EJBs могут быть введены в CDI бобы. Нет необходимости проводить какие-либо различия при введении одного в другую. Опять же, различные области обрабатываются CDI с помощью проксирования. Одним из исключений из этого является то, что CDI не поддерживает инъекцию удаленных EJBs, но это может быть реализовано путем написания простого метода производителя для него.

The javax.inject.Named аннотации, а также любые квалификаторы могут быть использованы на EJB, чтобы сопоставить его с точкой впрыска.

когда использовать какой Боб

как вы знаете, когда использовать какой фасоль? Простой.

никогда не используйте управляемые компоненты JSF, если вы не работаете в контейнере сервлетов и не хотите пытаться заставить CDI работать в Tomcat (хотя для этого есть некоторые архетипы Maven, поэтому нет оправдания).

в общем, вы должны использовать компоненты CDI, если вам не нужна расширенная функциональность, доступная в EJBs, таких как транзакционные функции. Вы можете написать свой собственный перехватчик, чтобы сделать транзакционные компоненты CDI, но на данный момент проще использовать EJB до CDI получает транзакционные CDI-бобы, которые находятся за углом. Если вы застряли в контейнере сервлетов и используете CDI, то либо рукописные транзакции, либо ваш собственный перехватчик транзакций-единственный вариант без EJBs.

Если вам нужно использовать @ViewScoped в CDI вы должны

  • использовать шов-лица или MyFaces CODI модуль. просто добавьте один из них в свой classpath и @ViewScoped будет работать в CDI. MyFaces КППР еще более солидная поддержка @ViewScoped
  • использовать MyFaces КППР по @ViewAccessScoped, это расширение, написанное поверх CDI Apache, просто скачать его и использовать @ViewAccessScoped аннотации вместо @ViewScoped.
  • использовать CDI @ConversationScoped и сделать его долго работает. Смотрите здесь для получения дополнительной информации.
  • использовать Omnifaces @ViewScoped аннотации

некоторые части украдены из здесь.

Да, это может сбить с толку.

для некоторых ЭМ исторические причины JSF и CDI используют одни и те же аннотации для областей, но из разных пакетов.

Как вы, вероятно, догадываетесь те из javax.faces.bean из спецификации JSF и не связаны с CDI. Не используйте их, если у вас нет очень веской причины для этого. И никогда не смешивайте их с аннотациями CDI от javax.ejb. Это приведет к явным бесконечным спискам ошибок и тонких аномалии.

Я вообще рекомендую вам просмотреть первые несколько (или даже больше) страниц превосходного сварить документации. Это должно поставить вас на путь для Java EE 6.

и не стесняйтесь задавать дополнительные вопросы здесь.

так как нет никаких ответов конкретно о @javax.annotation.ManagedBean, вот ссылка на ответ на подобный вопрос: Backing 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 тем более устаревает сейчас.