Являются ли @ManagedBeans устаревшими в JavaEE6 из-за @Named в CDI/Weld?
Из-за CDI (и его реализации Weld) каждый POJO в JEE6 может быть аннотирован @Named
, что делает POJO доступным для просмотра.
Означает ли это, что ManagedBeans теперь полностью устарели? Или я что то пропустил где @ManagedBean
все еще имеет смысл?
4 ответа
Короче, @ManagedBean
имеет смысл для приложений, которые используют JSF, но не используют JSR 299 (какова бы ни была причина). Ниже более длинное объяснение от Гэвина Кинга:
Re: Сравнения с аннотациями @ManagedBean в JSF2?:
Просматривая примеры Weld и более старую документацию по WebBeans, она выглядит как конкурент новым аннотациям @ManagedBean JSF 2.0. Есть ли какая-нибудь информация о том, когда мы хотим использовать один поверх другого?
Это хороший вопрос, и я не совсем согласен с ответами, которые были опубликованы до сих пор.
Новая спецификация EE Managed Beans определяет базовую модель компонентов для Java EE вместе с базовым набором сервисов контейнеров (
@Resource
,@PostConstruct
,@PreDestroy
).Идея состоит в том, что другие спецификации (начиная с EJB, CDI, JSF и новой спецификации Java Interceptors) основываются на этой базовой модели компонентов и уровне дополнительных услуг, например, управление транзакциями, внедрение безопасных зависимостей, перехватчики. Таким образом, на этом уровне управляемые bean-компоненты, CDI, перехватчики и спецификации EJB работают рука об руку и в значительной степени дополняют друг друга.
Теперь спецификация Managed Beans довольно открыта в отношении точного определения того, какие классы являются управляемыми bean-компонентами. Это обеспечивает
@ManagedBean
аннотация как один механизм, но она также позволяет другим спецификациям определять различные механизмы. Так, например:
Спецификация EJB говорит, что класс подчиняется определенным программным ограничениям с
@Stateless
или же@Stateful
аннотация, развернутая в EJB-банке, является управляемым компонентом.В спецификации CDI говорится, что любой класс с соответствующим конструктором, развернутым в "архиве развертывания компонента", является управляемым компонентом.
Учитывая, что EJB и CDI предоставляют возможно более удобные способы идентификации управляемого компонента, вы можете точно знать, что
@ManagedBean
нужен для. Ответ, на который ссылается Дэн, заключается в том, что если в вашей среде есть CDI (например, если вы используете EE6), то@ManagedBean
просто не очень нужно.@ManagedBean
действительно там для использования людьми, которые используют JSF2 без CDI.OTOH, если вы аннотируете боб
@ManagedBean
и у вас есть CDI в вашей среде, вы все равно можете использовать CDI для внедрения чего-либо в ваш компонент. Просто@ManagedBean
аннотация в этом случае не требуется.Подводя итог, если у вас есть CDI, он предоставляет гораздо лучшую модель программирования для
@ManagedBean
/@ManagedProperty
модель, которая JSF2 наследует от JSF1. Настолько превосходящий, что веб-профиль EE 6 не требует поддержки@ManagedProperty
и т.д. Идея в том, что вы должны просто использовать CDI.
У тебя есть выбор. Либо используйте @ManagedBean из JSF2 для привязки bean-компонентов к вашим формам, либо используйте аннотацию @Named из CDI. Если вы планируете делать только JSF, вы можете придерживаться @ManagedBean, но если вы хотите интегрироваться с EJB или использовать @ConversationScoped CDI, то идите по маршруту CDI.
Лично я считаю, что следующая версия JSF должна отказаться от @ManagedBean и стандартизировать CDI. Двойственность сбивает с толку новичков.
CDI не имеет области видимости, потому что у него нет понятия представления, поэтому, если вам нужна эта область, CDI в чистом виде не может этого сделать. Область видимости в основном означает область запроса + готовность к AJAX. Это не представление JSF, как страница с именем xyz.xhtml
даже если вы видите JSF <f:viewParam>
и лайки. Частый случай использования с bean-объектами видимости - как получить параметры GET в такой bean-компонент. Также прочитайте это.
Обратите внимание, что CDI скорее живет на уровне EJB/ обслуживания, чем на уровне JSF/ представления. Этот блог имеет хороший обзор.
В качестве таких @ManagedBean
не может быть полностью заменен CDI, опять же, если вы используете @ViewScoped
бобы - по крайней мере, без расширения CDI или использования модуля Seam 3 Faces. Использование bean-объектов в области видимости почти всегда происходит при использовании наборов GUI на основе AJAXed JSF 2, таких как RichFaces, PrimeFaces, IceFaces и т. Д.
Смешивание аннотаций из неправильных пакетов Java EE 6 может неожиданно вызвать проблемы, опять же при использовании RichFaces или аналогичного API:
@javax.faces.bean.ManagedBean
@javax.faces.bean.[Jsf]Scoped
предназначены для компонентов, используемых исключительно на уровне представления, здесь RichFaces, PrimeFaces и т. д. Некоторые богатые компоненты, похоже, имеют проблемы с вспомогательными компонентами, аннотированными CDI и JSF. Если вы получаете странное поведение от ваших bean-компонентов (или bean-компонентов, которые, похоже, ничего не делают), причиной может быть неправильное сочетание аннотаций.
Смешивание JSF и CDI, как
@javax.inject.Named
@javax.faces.bean.[Jsf]Scoped
Это возможно и работает в большинстве случаев, когда на него ссылаются страницы JSF, однако существуют некоторые малоизвестные проблемы / недостатки, например, при использовании области JSF, которой нет в CDI:
Также комбинация
@Named @ViewScoped
не будет работать как задумано. JSF-специфичный@ViewScoped
работает в сочетании со спецификой JSF@ManagedBean
только. Ваш CDI-специфичный@Named
будет вести себя как@RequestScoped
сюда. Либо использовать@ManagedBean
вместо@Named
или используйте CDI-специфичный@ConversationScoped
вместо@ViewScoped
,
затем
@javax.inject.Named
@javax.faces.bean.[Cdi]Scoped
может использоваться для компонентов CDI, на которые непосредственно ссылаются ваши страницы JSF AFAIK. До сих пор у меня не было проблем с вышеуказанными комбинациями, так что вы можете рассмотреть @ManagedBean
устарел здесь.
Остается сервисный уровень, здесь в основном транзакционные EJB-сервисные бины, объявленные как
@javax.ejb.*
в основном @javax.ejb.Stateless. Вы даже можете аннотировать и использовать EJB-файлы непосредственно со страниц JSF - хотя я не уверен, желателен ли этот дизайн. Для ссылки (добавления) любых компонентов, помеченных @javax.ejb.*, Например @Stateless
предпочитаю @Inject
над @EJB
как описано здесь. (Вероятно, предок этого ответа...)
Наконец, очень хороший обзор аннотаций Java EE 6 можно найти здесь: http://www.physics.usyd.edu.au/~rennie/javaEEReferenceSheet.html
Примечание: приведенная выше информация не от эксперта, а просто от моего взгляда новичков на эту нелепую путаницу спагетти с аннотациями Java EE 6. Больше понимания еще предстоит разработать. Я надеюсь, что этот ответ может быть общим, практическим ответом на эту путаницу - даже если он немного переборщил в контексте первоначального вопроса.
Как я только что прочитал в Справочнике по сварке (стр. 12), @ManagedBean теперь излишне:
Вы можете явно объявить управляемый компонент, аннотируя класс компонента @ManagedBean, но в CDI вам это не нужно. Согласно спецификации контейнер CDI обрабатывает любой класс, который удовлетворяет следующим условиям, как управляемый компонент:
- Это не нестатический внутренний класс. Это конкретный класс или аннотированный @Decorator.
- Он не аннотируется аннотацией, определяющей компонент EJB, и не объявляется как класс EJB-компонента в ejb-jar.xml.
- Он не реализует javax.enterprise.inject.spi.Extension.
- У него есть соответствующий конструктор - либо:
- у класса есть конструктор без параметров, или
- класс объявляет конструктор аннотированный @Inject.