Поддержка бобов (@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, но я не играл с этим лично.