wake-up-neo.com

Backing Beans (@ManagedBean) oder CDI Beans (@Named)?

Ich habe gerade angefangen zu lesen Core JavaServer Faces, 3rd Ed. und sie sagen dies (Hervorhebung von mir):

Es ist ein historischer Unfall, dass es für Beans, die in JSF-Seiten verwendet werden können, zwei separate Mechanismen gibt, CDI-Beans und JSF-verwaltete Beans. Es wird empfohlen, CDI-Beans zu verwenden, es sei denn, Ihre Anwendung muss auf einem einfachen Servlet-Runner wie Tomcat ausgeführt werden.

Warum? Sie liefern keine Begründung. Ich habe @ManagedBean Für alle Beans in einer Prototyp-Anwendung verwendet, die auf GlassFish 3 ausgeführt wird, und dabei sind mir keine Probleme aufgefallen. Es macht mir nichts aus, von @ManagedBean Nach @Named Zu migrieren, aber ich möchte wissen , warum ich mich die Mühe machen sollte .

105
Matt Ball

CDI wird gegenüber einfachem JSF bevorzugt, da CDI eine JavaEE-weite Abhängigkeitsinjektion ermöglicht. Sie können auch POJOs injizieren und verwalten lassen. Mit JSF können Sie nur eine Teilmenge dessen injizieren, was Sie mit CDI können.

62
Bozho

Verwenden Sie CDI.

Gemäß JSF 2.3 ist @ManagedBean veraltet . Siehe auch spec issue 1417 . Dies bedeutet, dass es keinen Grund mehr gibt, @ManagedBean vor @Named zu wählen. Dies wurde erstmals in der Mojarra 2.3.0 Beta-Version m06 implementiert.

enter image description here


Geschichte

Der Hauptunterschied besteht darin, dass @ManagedBean vom JSF-Framework verwaltet wird und nur über @ManagedProperty für andere von JSF verwaltete Beans verfügbar ist. @Named wird vom Anwendungsserver (dem Container) über das CDI-Framework verwaltet und ist über @Inject für alle Arten von containergesteuerten Artefakten wie @WebListener, @WebFilter, @WebServlet, @Path, @Stateless verfügbar. , etc und sogar einen JSF @ManagedBean. Von der anderen Seite an funktioniert @ManagedProperty nicht innerhalb eines @Named oder eines anderen von Containern verwalteten Artefakts. Es funktioniert wirklich nur innerhalb von @ManagedBean.

Ein weiterer Unterschied besteht darin, dass CDI tatsächlich Proxys einspeist, die im Zielbereich je nach Anforderung/Thread an die aktuelle Instanz delegieren (beispielsweise wie EJBs eingespritzt wurden). Dieser Mechanismus ermöglicht das Injizieren einer Bean mit einem engeren Bereich in eine Bean mit einem breiteren Bereich, was mit JSF @ManagedProperty nicht möglich ist. JSF "injiziert" hier die physische Instanz direkt durch Aufrufen eines Setters (das ist auch genau der Grund, warum ein Setter erforderlich ist, während dies bei @Inject nicht erforderlich ist ).

Obwohl dies kein direkter Nachteil ist - es gibt andere Möglichkeiten -, ist der Umfang von @ManagedBean einfach begrenzt. Aus der anderen Perspektive, wenn Sie nicht "zu viel" für @Inject verfügbar machen möchten, können Sie auch einfach Ihre verwalteten Beans @ManagedBean behalten. Es ist wie protected gegen public. Aber das zählt nicht wirklich.

Zumindest in JSF 2.0/2.1 besteht der Hauptnachteil der Verwaltung von JSF-Backing-Beans durch CDI darin, dass es kein CDI-Äquivalent zu @ViewScoped gibt. Der @ConversationScoped wird geschlossen, muss jedoch manuell gestartet und gestoppt werden, und an die Ergebnis-URLs wird ein hässlicher Anforderungsparameter cid angehängt. MyFaces CODI vereinfacht dies, indem es JSFs javax.faces.bean.ViewScoped vollständig transparent mit CDI verbindet, sodass Sie nur @Named @ViewScoped ausführen können. Dabei wird jedoch ein hässlicher Anforderungsparameter windowId an Ergebnis-URLs angehängt, auch bei einfacher Vanilla-Navigation von Seite zu Seite. OmniFaces löst dies alles mit einem echten CDI @ViewScoped , der den Gültigkeitsbereich des Beans wirklich an den JSF-Ansichtsstatus anstatt an einen beliebigen Anforderungsparameter bindet.

JSF 2.2 (das 3 Jahre nach dieser Frage/Antwort veröffentlicht wird) bietet eine neue, vollständig CDI-kompatible @ViewScoped-Annotation, die den Geschmack von javax.faces.view.ViewScoped hat. JSF 2.2 wird sogar mit einem @FlowScoped nur für CDI ausgeliefert, der kein @ManagedBean-Äquivalent hat, wodurch JSF-Benutzer zu CDI gedrängt werden. Es wird erwartet, dass @ManagedBean und Freunde gemäß Java EE 8 veraltet sind. Wenn Sie derzeit noch @ManagedBean verwenden, wird dringend empfohlen, auf CDI zu wechseln, um für zukünftige Upgrade-Pfade vorbereitet zu sein. CDI ist in Java EE Web Profile-kompatiblen Containern wie WildFly, TomEE und GlassFish verfügbar. Für Tomcat müssen Sie es separat installieren, genauso wie Sie es bereits für JSF getan haben. Siehe auch Wie installiere ich CDI in Tomcat?

168
BalusC

Mit Java EE 6 und CDI haben Sie unterschiedliche Optionen für Managed Beans

  • @javax.faces.bean.ManagedBean Bezieht sich auf JSR 314 und wurde mit JSF 2.0 eingeführt. Das Hauptziel war, die Konfiguration in der Datei faces-config.xml zu vermeiden, um die Bean innerhalb einer JSF-Seite zu verwenden.
  • @javax.annotation.ManagedBean(“myBean”) ist in JSR 316 definiert. Es verallgemeinert die JSF-verwalteten Beans zur Verwendung an anderer Stelle in Java EE
  • @javax.inject.Named(“myBean”) sind fast die gleichen wie oben, außer dass Sie eine beans.xml-Datei im web/WEB-INF-Ordner benötigen, um CDI zu aktivieren.
13
h2mch

Ich habe CDI in GlassFish 3.0.1 verwendet, aber um es zum Laufen zu bringen, musste ich das Seam 3 Framework (Weld) importieren. Das hat ganz gut geklappt.

In GlassFish 3.1 hat CDI aufgehört zu arbeiten, und Seam Weld hat aufgehört, damit zu arbeiten. Ich habe ein Fehler in diesem geöffnet, aber noch keine Fehlerbehebung gesehen. Ich musste meinen gesamten Code konvertieren, um die Anmerkungen von javax.faces. * Zu verwenden, aber ich plane, zu CDI zurückzukehren, sobald sie funktionieren.

Ich bin damit einverstanden, dass Sie CDI verwenden sollten, aber ein Problem, das ich noch nicht gelöst habe, ist, was mit der @ViewScoped-Annotation zu tun ist. Ich habe viel Code, der davon abhängt. Es ist nicht klar, ob @ViewScoped funktioniert, wenn Sie @ManagedBean nicht damit verwenden. Wenn jemand dies klarstellen kann, würde ich es begrüßen.

2
AlanObject

Ein guter Grund, auf CDI umzusteigen: Sie könnten eine gemeinsame sitzungsspezifische Ressource (z. B. Benutzerprofil) @Inject In beiden von JSF verwalteten Beans und REST Services (dh Jersey/JAX-RS).

Andererseits ist @ViewScoped Ein zwingender Grund, sich an JSF @ManagedBean Zu halten - insbesondere für alles mit signifikantem AJAX. In CDI gibt es dafür keinen Standardersatz.

Scheint, dass es Unterstützung für einen @ViewScoped - wie eine Annotation für CDI-Beans gibt, aber ich habe nicht persönlich damit gespielt.

http://seamframework.org/Seam3/FacesModule

0
wrschneider