Ich habe das Gefühl, dass die Java EE 6-Spezifikation ein wenig durcheinander ist. Es gibt mehrere Sätze von Anmerkungen.
Wir haben javax.ejb
Anmerkungen wie @Stateful
und @Stateless
zum Erstellen von EJBs.
Es gibt auch eine @javax.annotation.ManagedBean
Möglichkeit, eine verwaltete Bean zu erstellen.
Es gibt Anmerkungen in javax.enterprise.context
like @SessionScoped
und @RequestScoped
.
Darüber hinaus gibt es auch @ManagedBean
und @SessionScoped
/ @RequestScoped
Anmerkungen im javax.faces.bean
Paket.
Und um das Ereignis noch komplizierter zu gestalten, gibt es ein Paket javax.inject
mit @Named
Anmerkungen.
Kann jemand bitte beschreiben, wie sie miteinander verwandt sind?
Wo kann ich @EJB
, @Inject
oder @ManagedPropery
andere Bohnen zu injizieren?
java
jakarta-ee
java-ee-6
cdi
Piotr Gwiazda
quelle
quelle
Antworten:
Lassen Sie mich zunächst einige Klarstellungen vornehmen:
Definition einer verwalteten Bean: Im Allgemeinen ist eine verwaltete Bean ein Objekt, dessen Lebenszyklus (Konstruktion, Zerstörung usw.) von einem Container verwaltet wird.
In Java ee gibt es viele Container, die den Lebenszyklus ihrer Objekte verwalten, z. B. JSF-Container, EJB-Container, CDI-Container, Servlet-Container usw.
Alle diese Container arbeiten unabhängig voneinander. Sie booten in der Anwendungsserverinitialisierung und scannen Klassen aller Artefakte, einschließlich JAR-, EJB-JAR-, War- und Ear-Dateien, in der Bereitstellungszeit und sammeln und speichern einige Metadaten darüber, wenn Sie ein Objekt benötigen einer Klasse zur Laufzeit geben sie Ihnen Instanzen dieser Klassen und nach Beendigung des Jobs zerstören sie sie.
Wir können also sagen, dass wir:
Wenn Sie also das Managed Bean-Wort sehen, sollten Sie nach dem Kontext oder Typ des Wortes fragen (JSF, CDI, EJB usw.).
Dann könnten Sie sich fragen, warum wir viele dieser Container haben: AFAIK, Java EE-Leute wollten ein Abhängigkeitsinjektions-Framework, aber sie konnten nicht alle Anforderungen in einer Spezifikation erfassen, weil sie die zukünftigen Anforderungen nicht vorhersagen konnten und EJB 1.0 und dann erstellten 2.0 und dann 3.0 und jetzt 3.1, aber das Ziel von EJB waren nur einige Anforderungen (Transaktion, verteiltes Komponentenmodell usw.).
Gleichzeitig (parallel) erkannten sie, dass sie auch JSF unterstützen müssen, dann stellten sie JSF-verwaltete Beans und einen weiteren Container für JSF-Beans her und betrachteten es als ausgereiften DI-Container, aber es war immer noch kein vollständiger und ausgereifter Container.
Danach haben Gavin King und einige andere nette Leute CDI gemacht, das ist der ausgereifteste DI-Container, den ich je gesehen habe. CDI (inspiriert von Seam2, Guice und Spring) wurde entwickelt, um die Lücke zwischen JSF und EJB und vielen anderen nützlichen Dingen wie Pojo-Injektion, Herstellungsmethoden, Abfangjägern, Dekorateuren, Integrations-SPI, sehr flexibel usw. zu schließen Was EJB- und JSF-verwaltete Beans tun, können wir nur einen ausgereiften und leistungsstarken DI-Container haben. Aber aus Gründen der Abwärtskompatibilität und aus politischen Gründen wollen Java EE-Leute sie behalten !!!
Hier finden Sie den Unterschied und die Anwendungsfälle für jeden dieser Typen:
JSF Managed Beans, CDI Beans und EJBs
JSF wurde ursprünglich mit einem eigenen verwalteten Bean- und Abhängigkeitsinjektionsmechanismus entwickelt, der für JSF 2.0 um annotationsbasierte Beans erweitert wurde. Als CDI mit Java EE 6 veröffentlicht wurde, wurde es als verwaltetes Bean-Framework für diese Plattform angesehen, und natürlich haben EJBs sie alle veraltet, da es sie schon seit mehr als einem Jahrzehnt gibt.
Das Problem ist natürlich zu wissen, welche und wann sie verwendet werden sollen.
Beginnen wir mit den einfachsten, JSF Managed Beans.
JSF Managed Beans
Kurz gesagt, verwenden Sie sie nicht, wenn Sie für Java EE 6 entwickeln und CDI verwenden. Sie bieten einen einfachen Mechanismus für die Abhängigkeitsinjektion und die Definition von Backing Beans für Webseiten, sind jedoch weitaus weniger leistungsfähig als CDI Beans.
Sie können mithilfe der
@javax.faces.bean.ManagedBean
Anmerkung definiert werden, die einen optionalen Namensparameter verwendet. Dieser Name kann verwendet werden, um auf die Bean von JSF-Seiten zu verweisen.Der Bereich kann auf die Bean angewendet werden, indem einer der verschiedenen im
javax.faces.bean
Paket definierten Bereiche verwendet wird , einschließlich der Bereiche Anforderung, Sitzung, Anwendung, Ansicht und Benutzerdefiniert.JSF-Beans können ohne manuelle Codierung nicht mit anderen Beansorten gemischt werden.
CDI Bohnen
CDI ist das Bean-Management- und Abhängigkeitsinjektions-Framework, das als Teil von Java EE 6 veröffentlicht wurde und eine vollständige, umfassende Managed-Bean-Funktion enthält. CDI-Beans sind weitaus fortschrittlicher und flexibler als einfache JSF-verwaltete Beans. Sie können Interceptors, Konversationsumfang, Ereignisse, typsichere Injektionen, Dekorateure, Stereotypen und Herstellungsmethoden verwenden.
Um CDI-Beans bereitzustellen, müssen Sie eine Datei mit dem Namen beans.xml in einem META-INF-Ordner im Klassenpfad ablegen. Sobald Sie dies tun, wird jede Bean im Paket zu einer CDI-Bean. Es gibt viele Funktionen in CDI, zu viele, um sie hier zu behandeln. Als Kurzreferenz für JSF-ähnliche Funktionen können Sie den Umfang der CDI-Bean mithilfe eines der im
javax.enterprise.context
Paket definierten Bereiche definieren (nämlich Anforderung, Konversation) , Sitzungs- und Anwendungsbereiche). Wenn Sie die CDI-Bean von einer JSF-Seite verwenden möchten, können Sie ihr mithilfe derjavax.inject.Named
Anmerkung einen Namen geben . Um eine Bean in eine andere Bean einzufügen, kommentieren Sie das Feld mitjavax.inject.Inject
Annotation.Eine automatische Injektion wie die oben definierte kann durch die Verwendung von Qualifikatoren gesteuert werden, die dazu beitragen können, die spezifische Klasse zu erreichen, die Sie injizieren möchten. Wenn Sie mehrere Zahlungsarten haben, können Sie ein Qualifikationsmerkmal hinzufügen, ob es asynchron ist oder nicht. Sie können die
@Named
Annotation zwar als Qualifikationsmerkmal verwenden, sollten dies jedoch nicht tun, da sie zum Anzeigen der Beans in EL bereitgestellt wird.CDI behandelt die Injektion von Bohnen mit nicht übereinstimmenden Bereichen mithilfe von Proxys. Aus diesem Grund können Sie eine Bean mit Anforderungsbereich in eine Bean mit Sitzungsbereich einfügen, und die Referenz ist bei jeder Anforderung weiterhin gültig, da der Proxy für jede Anforderung erneut eine Verbindung zu einer Live-Instanz der Bean mit Anforderungsbereich herstellt.
CDI unterstützt auch Interceptors, Ereignisse, den neuen Konversationsbereich und viele andere Funktionen, was es zu einer viel besseren Wahl gegenüber von JSF verwalteten Beans macht.
EJB
EJBs sind älter als CDI-Beans und ähneln in gewisser Weise CDI-Beans und sind auf andere Weise sehr unterschiedlich. In erster Linie besteht der Unterschied zwischen CDI-Beans und EJBs darin, dass EJBs:
Die beiden Arten von EJBs werden als zustandslos und zustandsbehaftet bezeichnet. Statuslose EJBs können als thread-sichere Single-Use-Beans betrachtet werden, die keinen Status zwischen zwei Webanforderungen beibehalten. Stateful EJBs halten den Status und können erstellt und so lange herumgesessen werden, wie sie benötigt werden, bis sie entsorgt werden.
Das Definieren eines EJB ist einfach. Fügen Sie der Klasse entweder eine
javax.ejb.Stateless
oder einejavax.ejb.Stateful
Anmerkung hinzu.Statuslose Beans müssen einen abhängigen Bereich haben, während ein Stateful Session Bean einen beliebigen Bereich haben kann. Standardmäßig sind sie transaktional, Sie können jedoch die Annotation für Transaktionsattribute verwenden.
Während sich EJBs und CDI-Beans hinsichtlich der Funktionen stark unterscheiden, ist das Schreiben des Codes zum Integrieren sehr ähnlich, da CDI-Beans in EJBs und EJBs in CDI-Beans injiziert werden können. Es ist nicht erforderlich, beim Einspritzen in das andere zu unterscheiden. Auch hier werden die verschiedenen Bereiche von CDI mithilfe von Proxy behandelt. Eine Ausnahme hiervon ist, dass CDI die Injektion von Remote-EJBs nicht unterstützt, dies jedoch durch Schreiben einer einfachen Herstellermethode implementiert werden kann.
Die
javax.inject.Named
Annotation sowie alle Qualifikationsmerkmale können auf einem EJB verwendet werden, um sie einem Injektionspunkt zuzuordnen.Wann welche Bohne zu verwenden ist
Woher wissen Sie, wann Sie welche Bohne verwenden müssen? Einfach.
Verwenden Sie niemals JSF-verwaltete Beans, es sei denn, Sie arbeiten in einem Servlet-Container und möchten nicht versuchen, CDI in Tomcat zum Laufen zu bringen (obwohl es dafür einige Maven-Archetypen gibt, gibt es keine Entschuldigung).
Im Allgemeinen sollten Sie CDI-Beans verwenden, es sei denn, Sie benötigen die in den EJBs verfügbaren erweiterten Funktionen, z. B. Transaktionsfunktionen. Sie können Ihren eigenen Interceptor schreiben, um CDI-Beans transaktional zu machen. Derzeit ist es jedoch einfacher, einen EJB zu verwenden, bis CDI transaktionale CDI-Beans erhält, die sich gleich um die Ecke befinden. Wenn Sie in einem Servlet-Container stecken bleiben und CDI verwenden, sind entweder handgeschriebene Transaktionen oder Ihr eigener Transaktions-Interceptor die einzige Option ohne EJBs.
Wenn Sie
@ViewScoped
in CDI verwenden müssen, sollten Sie@ViewScoped
funktioniert in CDI. MyFaces CODI unterstützt @ViewScoped noch solider@ViewAccessScoped
ist eine Erweiterung, die von Apache auf CDI geschrieben wurde. Laden Sie sie einfach herunter und verwenden Sie@ViewAccessScoped
stattdessen Annotation@ViewScoped
.@ConversationScoped
und machen Sie es langlebig. Sehen Sie hier für weitere Informationen .Einige Teile wurden von hier gestohlen .
quelle
@ManagedProperty("#{someBean})"
der richtige Weg?@Named
und@javax.enterprise.context.RequestScoped
kommentieren und die CDI-Injection mit @Inject annotation verwenden. Verwenden Sie keine von jsf verwalteten Beans, wenn Sie dies nicht müssen;).Ja, das kann verwirrend sein.
Für einige ehm historischen Gründen JSF und CDI werden mit den gleichen Annotationen für Bereiche, aber aus verschiedenen Paketen.
Wie Sie wahrscheinlich erraten haben, stammen diese von
javax.faces.bean
aus der JSF-Spezifikation und sind nicht mit CDI verwandt. Verwenden Sie sie nur, wenn Sie einen sehr guten Grund dafür haben. Und mischen Sie sie niemals mit CDI-Anmerkungen vonjavax.ejb
. Dies führt zu einer endlosen Liste von Fehlern und subtilen Anomalien.Ich empfehle generell, dass Sie die ersten paar (oder sogar mehr) Seiten der hervorragenden Schweißdokumentation überfliegen . Dies sollte Sie auf den richtigen Weg für Java EE 6 bringen.
Und zögern Sie nicht, hier weitere Fragen zu stellen.
quelle
@javax.annotation.ManagedBean
nutzlos ist, da CDI alle Klassen als verwaltete Beans behandelt. Stimmt das?Da es keine spezifischen Antworten gibt, finden Sie
@javax.annotation.ManagedBean
hier einen Link zur Antwort auf eine ähnliche Frage: Backing Beans (@ManagedBean) oder CDI Beans (@Named)? . Die Spezifikation finden Sie unter http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/ . Es scheint mir also@javax.annotation.ManagedBean
eine Verallgemeinerung von zu sein@javax.faces.bean.ManagedBean
.Nach allem, was ich zusammengetragen habe, werden JSF Managed Beans zugunsten von CDI Beans auslaufen (möglicherweise von JSF 2.3 veraltet?). Ich denke, dies
@javax.annotation.ManagedBean
wird jetzt umso veralteter.quelle
@Named
wird@ManagedBean
in Zukunft ersetzen ?@Named
Beans JSF ersetzen werden@ManagedBeans
, z. B. in stackoverflow.com/questions/4347374/… . BalusC sagt: "Die Erwartung ist, dass @ManagedBean und Freunde gemäß Java veraltet sind EE 8. ".