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 .
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.
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.
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?
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.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.
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.