Поддержка бобов (@ManagedBean) или CDI-бинов (@Named)?

Я только начал читать через Core JavaServer Faces, 3-е изд. и они говорят это (выделение мое):

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

Зачем? Они не дают никакого оправдания. Я использую @ManagedBean для всех компонентов в прототипе приложения, работающего на GlassFish 3, и я действительно не заметил никаких проблем с этим. Я не против мигрировать @ManagedBean в @Named, но я хочу знать, почему я должен беспокоиться.

5 ответов

Решение

CDI предпочтительнее простого JSF, потому что CDI допускает внедрение зависимостей в масштабе JavaEE. Вы также можете вводить POJO и управлять ими. С JSF вы можете внедрить только часть того, что вы можете с помощью CDI.

Используйте CDI.

Согласно JSF 2.3, @ManagedBean устарела. Смотрите также спецификацию 1417. Это означает, что больше нет причин выбирать @ManagedBean над @Named, Впервые это было реализовано в Mojarra 2.3.0 бета-версия m06.


история

Основное отличие состоит в том, @ManagedBean управляется фреймворком JSF и только через @ManagedProperty доступны для других управляемых компонентов JSF. @Named управляется сервером приложений (контейнером) через инфраструктуру CDI и осуществляется через @Inject доступны для любого вида управляемого артефактом контейнера @WebListener, @WebFilter, @WebServlet, @Path, @Stateless и т.д. и даже JSF @ManagedBean, С другой стороны, @ManagedProperty не работает внутри @Named или любой другой управляемый контейнером артефакт. Работает реально только внутри @ManagedBean,

Другое отличие состоит в том, что CDI фактически внедряет прокси-серверы, делегирующие текущему экземпляру в целевой области на основе запроса / потока (например, как то, как EJB были введены). Этот механизм позволяет вводить компонент с более узкой областью действия в компонент с более широкой областью действия, что невозможно в JSF @ManagedProperty, JSF "внедряет" сюда физический экземпляр напрямую, вызывая установщик (именно поэтому и требуется установщик, в то время как это не требуется с @Inject).

Хотя это не является прямым недостатком - существуют и другие способы - сфера @ManagedBean просто ограничен. С другой стороны, если вы не хотите подвергать "слишком много" для @Inject Вы также можете просто оставить свои управляемые бобы @ManagedBean, Это как protected против public, Но это на самом деле не считается.

По крайней мере, в JSF 2.0/2.1 основным недостатком управления компонентами поддержки JSF с помощью CDI является отсутствие CDI-эквивалента @ViewScoped, @ConversationScoped близко, но все еще требует ручного запуска и остановки, и это добавляет некрасиво cid Параметр запроса к конечным URL. MyFaces CODI делает это проще благодаря полностью прозрачному соединению JSF javax.faces.bean.ViewScoped на CDI, так что вы можете просто сделать @Named @ViewScoped Однако добавляет, что уродливый windowId Параметр запроса к конечным URL-адресам, также при простой навигации по страницам. OmniFaces решает все это с настоящим CDI @ViewScoped который действительно связывает область действия bean-компонента с состоянием представления JSF, а не с произвольным параметром запроса.

JSF 2.2 (выпущенный через 3 года после этого вопроса / ответа) предлагает новый полностью совместимый с CDI @ViewScoped аннотация из коробки в аромате javax.faces.view.ViewScoped, JSF 2.2 даже поставляется только с CDI @FlowScoped который не имеет @ManagedBean эквивалентно, тем самым подталкивая пользователей JSF к CDI. Ожидается, что @ManagedBean и друзья будут устаревшими согласно Java EE 8. Если вы все еще используете @ManagedBean Поэтому настоятельно рекомендуется переключиться на CDI, чтобы подготовиться к будущим путям обновления. CDI легко доступен в контейнерах, совместимых с веб-профилем Java EE, таких как WildFly, TomEE и GlassFish. Для Tomcat вы должны установить его отдельно, точно так же, как вы уже сделали для JSF. Смотрите также Как установить CDI в Tomcat?

С Java EE 6 и CDI у вас есть разные варианты для управляемых компонентов

  • @javax.faces.bean.ManagedBean это относится к JSR 314 и был введен с JSF 2.0. Основная цель состояла в том, чтобы избежать настройки в файле face-config.xml для использования bean-компонента внутри JSF-страницы.
  • @javax.annotation.ManagedBean(“myBean”) определяется JSR 316. Он обобщает управляемые компоненты JSF для использования в других местах в Java EE
  • @javax.inject.Named(“myBean”) почти такие же, как и выше, за исключением того, что вам нужен файл beans.xml в папке web/WEB-INF для активации CDI.

Я использовал CDI в GlassFish 3.0.1, но чтобы заставить его работать, мне пришлось импортировать фреймворк Seam 3 (Weld). Это сработало довольно хорошо.

В GlassFish 3.1 CDI перестал работать, и Seam Weld перестал работать с ним. Я открыл ошибку на этом, но еще не видел ее исправленной. Мне пришлось преобразовать весь мой код в аннотации javax.faces.*, Но я планирую вернуться к CDI, как только он заработает.

Я согласен с тем, что вы должны использовать CDI, но одна проблема, которую я до сих пор не решил, - что делать с аннотацией @ViewScoped. У меня много кода, который зависит от этого. Не ясно, работает ли @ViewScoped, если вы не используете @ManagedBean с ним. Если кто-то может уточнить это, я был бы признателен.

Одна веская причина для перехода на CDI: у вас может быть общий ресурс в области сеанса (например, профиль пользователя) @InjectОн работал как с управляемыми JSF-компонентами, так и с сервисами REST (например, Jersey/JAX-RS).

С другой стороны, @ViewScoped является веской причиной придерживаться JSF @ManagedBean - особенно для чего-либо со значительным AJAX. В CDI нет стандартной замены для этого.

Кажется, что он может иметь некоторую поддержку @ViewScopedКак аннотация для бобов CDI, но я не играл с этим лично.

http://seamframework.org/Seam3/FacesModule

Другие вопросы по тегам