Резервное копирование beans (@ManagedBean) или CDI beans (@Named)?

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

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

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

Ответ 1

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

Ответ 2

Использовать CDI.

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

введите описание изображения здесь


История

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

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

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

По крайней мере, в JSF 2.0/2.1 основным недостатком управления поддержкой JSF beans по 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-only @FlowScoped, который не имеет эквивалента @ManagedBean, тем самым подталкивая пользователей JSF к CDI. Ожидается, что @ManagedBean и друзья будут устаревать согласно Java EE 8. Если вы все еще используете @ManagedBean, поэтому настоятельно рекомендуется переключиться на CDI, чтобы быть готовым к будущим путям обновления. CDI легко доступен в контейнерах, совместимых с Java EE Web Profile, таких как WildFly, TomEE и GlassFish. Для Tomcat вы должны установить его отдельно, точно так же, как вы уже делали для JSF. См. Также Как установить CDI в Tomcat?

Ответ 3

С Java EE 6 и CDI у вас есть другой вариант для Managed Beans

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

Ответ 4

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

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

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

Ответ 5

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

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

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

http://seamframework.org/Seam3/FacesModule