Оброблення квасолі (@ManagedBean) або CDI Beans (@Named)?


109

Я щойно почав читати через Core JavaServer Faces, 3rd Ed. і вони говорять це (наголос мій):

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

Чому? Вони не дають жодного обґрунтування. Я використовую @ManagedBeanдля всіх бобів у прототипі програми, що працює на GlassFish 3, і я не дуже помітив жодних проблем з цим. Я не особливо проти міграції з @ManagedBeanмісця @Named, але хочу знати, чому я повинен турбуватися .



4
@Bozho: це питання досить схоже, але, прочитавши відповідь Паскаля кілька разів, я все ще не розумію, чому CDI набагато вищий. Я не знаю CDI, і я радий дізнатися його, оскільки це "краще". Чому краще?
Метт-бал

"якщо тільки ваша програма не повинна працювати на звичайному сервлетському бігуні, такому як Tomcat", я використовую лише tomcat і настійно рекомендую CDI. Tomcat може це добре підтримати
Карл Кілден

1
@ KarlKildén "звичайний сервлет-бігун" відноситься до контейнера сервлетів, не здатних до CDI. На момент написання Tomcat не підтримував CDI, за винятком зовсім магії.
Thorbjørn Ravn Andersen

Відповіді:


64

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


Отже, я можу ввести екземпляр майже будь-якого класу (за умови, що він має "правильний матеріал" - що це, просто конструктор без аргументів? ) З CDI, тоді як мені потрібно використовувати, @ManagedBeanякщо я хочу вставити його з простою JSF?
Метт-бал

3
@MattBall Matt через роки, чи можете ви прокоментувати цю міграцію?
Корай Тугай

5
@KorayTugay Я не торкався цього коду з червня 2011 року, але я перейшов на CDI і все працювало чудово. Я радий відповісти на будь-які конкретні запитання якнайкраще в моїй пам’яті, якщо у вас є.
Метт Бал

170

Використовуйте CDI.

Відповідно з JSF 2.3, @ManagedBeanє застарілим . Дивіться також специфікацію випуску 1417 . Це означає , що є більше не причина , щоб вибрати @ManagedBeanбільш @Named. Це було вперше реалізовано в бета-версії m06r Mojarra 2.3.0.

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


Історія

Основна відмінність полягає в тому, що @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який дійсно прив'язує область бобу до стану перегляду 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?


4
Я створив beans.xml, перетворив @ManagedBeanрезервні боби @Namedі перетворив їх @ManagedPropertyна @Inject. Все добре зі світом. Однак якщо я поміняю свої @EJBанотації на @Inject, розгортання не працює ( org.jboss.weld.exceptions.DeploymentException) з повідомленням WELD-001408 Injection point has unsatisfied dependencies. Чи повинен я насправді використовувати @Injectінжектор EJB без інтерфейсу в @Namedбоб, або я повинен дотримуватися @EJB? EJB упаковані в JAR JJB, у тому ж EAR, що і ВІЙНА, що містить мої CDI-боби.
Метт Баль

Це має просто працювати. Ви все ще стикаєтеся з цією проблемою з поточною версією Weld?
BalusC

На жаль, я не міг сказати. Це питання від 2 роботодавців та> 2 роки тому. Виходячи зі свого старого коментаря до відповіді Божо, я, мабуть, перейшов на CDI / @Named.
Метт Бал

"MyFaces CODI полегшує повне прозоре з'єднання JSF з javax.faces.bean.ViewScoped до CDI, щоб ви могли просто робити @Named @ViewScoped, однак додає некрасивий параметр запиту windowId до вихідних URL-адрес, також на звичайній навігації зі сторінки на сторінку ванілі." Зауважте, що для DeltaSpike це більше не відповідає дійсності. Ви можете відключити параметри URL-адреси dsId та windowId, якщо вам не потрібен діапазон вікон.
січень

1
@Jan: А тим часом OmniFaces також має JSF 2.2-подібний @ViewScopedдля JSF 2.0 / 2.1: showcase.omnifaces.org/cdi/ViewScoped
BalusC

16

У Java EE 6 та CDI у вас є різні варіанти керованих бобів

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

1
Яка різниця між першими двома?
Метт Бал

Метою першої анотації є / було замінити конфігурацію бобів у face-config.xml для використання в JSF. Другий копіює концепцію в "контейнер java ee 6". Він має більше функцій (наприклад, анотації @PostConstruct та @PreDestroy), але також доступний на сторінці JSF (з мовою виразів).
h2mch

1
для чого потрібен beans.xmlфайл? Чи справді це і сьогодні?
Туфір

2
Ні, з JavaEE7 вам більше не потрібен beans.xml. дивіться docs.oracle.com/javaee/7/tutorial/doc/cdi-adv001.htm
h2mch

1
З JavaEE7 вам не потрібен beans.xml: docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm (правильне посилання) blogs.oracle.com/theaquarium/entry/… ( Увімкнення CDI за замовчуванням на Java EE 7)
М. Атіф Ріаз

2

Я використовував CDI в GlassFish 3.0.1, але для його роботи мені довелося імпортувати рамку Seam 3 (Weld). Це спрацювало досить добре.

У GlassFish 3.1 CDI припинив свою роботу, а Seam Weld перестав працювати з ним. Я відкрив помилку на цьому, але ще не бачив його виправленого. Мені довелося перетворити весь код на використання javax.faces. * Анотації, але я планую повернутися до CDI, як тільки вони працюватимуть.

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


-1

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

З іншого боку, @ViewScopedце вагомий привід дотримуватися JSF @ManagedBean- особливо для чогось із значним AJAX. Не існує стандартної заміни для цього в CDI.

Здається, він може мати деяку підтримку для @ViewScopedподібної анотації до CDI-бобів, але я особисто не грав з цим.

http://seamframework.org/Seam3/FacesModule

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.