Ответ 1
CDI предпочтительнее простого JSF, потому что CDI допускает инъекцию зависимостей JavaEE. Вы также можете вводить POJO и позволять им управлять. С JSF вы можете вводить только подмножество того, что вы можете с помощью CDI.
Я только начал читать Core JavaServer Faces, 3-е изд., и они говорят это (внимание мое):
Это историческая авария, что есть два отдельных механизма: CDI beansи JSF управляется beans, для beans, который может использоваться на страницах JSF. Мы предлагаем что вы используете CDI beans, если ваше приложение не должно работать на одном сервлете как Tomcat.
Почему? Они не обеспечивают любого обоснования. Я использовал @ManagedBean
для всех beans в прототипном приложении, запущенном на GlassFish 3, и я не заметил никаких проблем с этим. Мне не особенно интересно перейти от @ManagedBean
в @Named
, но я хочу знать , почему я должен беспокоиться.
CDI предпочтительнее простого JSF, потому что CDI допускает инъекцию зависимостей JavaEE. Вы также можете вводить POJO и позволять им управлять. С JSF вы можете вводить только подмножество того, что вы можете с помощью 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?
С 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.Я использовал CDI в GlassFish 3.0.1, но чтобы заставить его работать, мне пришлось импортировать структуру Seam 3 (Weld). Это работало очень хорошо.
В GlassFish 3.1 CDI перестала работать, и Seam Weld прекратил работать с ним. Я открыл ошибку в этом, но пока не видел его исправленным. Мне пришлось преобразовать весь мой код в использование аннотаций javax.faces. *, Но я планирую вернуться к CDI, как только они его заработают.
Я согласен, что вы должны использовать CDI, но одна проблема, которую я еще не видел, - это что делать с аннотацией @ViewScoped. У меня много кода, который зависит от него. Неясно, работает ли @ViewScoped, если вы не используете @ManagedBean с ним. Если кто-нибудь может это прояснить, я был бы признателен.
Одна из веских причин для перехода на CDI: у вас может быть общий ресурс с ограниченным доступом (например, профиль пользователя) @Inject
в оба управляемых JSF сервисах beans и REST (например, Jersey/JAX-RS).
С другой стороны, @ViewScoped
является веской причиной для использования JSF @ManagedBean
- особенно для чего-либо со значительным AJAX. В CDI нет стандартной замены для этого.
Кажется, что он может поддерживать некоторую аннотацию @ViewScoped
для CDI beans, но я не играл с ней лично.