Mir ist aufgefallen, dass es verschiedene Bohnenbereiche gibt wie:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Was ist der Zweck von jedem? Wie wähle ich einen geeigneten Bereich für meine Bohne aus?
Mir ist aufgefallen, dass es verschiedene Bohnenbereiche gibt wie:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Was ist der Zweck von jedem? Wie wähle ich einen geeigneten Bereich für meine Bohne aus?
Antworten:
Es repräsentiert den Umfang (die Lebensdauer) der Bohne. Dies ist leichter zu verstehen, wenn Sie mit der Funktionsweise einer grundlegenden Servlet-Webanwendung vertraut sind: Wie funktionieren Servlets? Instanziierung, Sitzungen, gemeinsam genutzte Variablen und Multithreading .
@Request/View/Flow/Session/ApplicationScoped
Eine @RequestScoped
Bean lebt so lange wie ein einzelner HTTP-Anforderungs-Antwort-Zyklus (beachten Sie, dass eine Ajax-Anforderung auch als einzelne HTTP-Anforderung zählt). Eine @ViewScoped
Bean lebt so lange, wie Sie mit derselben JSF-Ansicht durch Postbacks interagieren, die Aktionsmethoden aufrufen, die null
/ void
ohne Navigation / Umleitung zurückgeben. Eine @FlowScoped
Bean lebt so lange, wie Sie durch die angegebene Sammlung von Ansichten navigieren, die in der Flow-Konfigurationsdatei registriert sind. Eine @SessionScoped
Bean lebt so lange wie die eingerichtete HTTP-Sitzung. Eine @ApplicationScoped
Bean lebt so lange, wie die Webanwendung ausgeführt wird. Beachten Sie, dass der CDI @Model
im Grunde ein Stereotyp für ist @Named @RequestScoped
, daher gelten dieselben Regeln.
Welcher Bereich ausgewählt werden soll, hängt ausschließlich von den Daten (dem Status) ab, die die Bean enthält und darstellt. Verwendung @RequestScoped
für einfache und nicht Ajax-Formulare / Präsentationen. Verwendung @ViewScoped
für umfangreiche Ajax-fähige dynamische Ansichten (Ajax-basierte Validierung, Rendering, Dialoge usw.). Verwendung @FlowScoped
für das Muster "Assistent" ("Fragebogen") zum Sammeln von Eingabedaten, die über mehrere Seiten verteilt sind. Verwendung @SessionScoped
für kundenspezifische Daten, z. B. den angemeldeten Benutzer und Benutzereinstellungen (Sprache usw.). Verwendung @ApplicationScoped
für anwendungsweite Daten / Konstanten, z. B. Dropdown-Listen, die für alle gleich sind, oder verwaltete Beans ohne Instanzvariablen und mit nur Methoden.
Wenn eine @ApplicationScoped
Bean für Daten mit Sitzungs- / Ansichts- / Anforderungsbereich missbraucht wird, wird sie für alle Benutzer freigegeben, sodass jeder andere die Daten des anderen sehen kann, was einfach falsch ist. Wenn eine @SessionScoped
Bean für Daten mit Ansichts- / Anforderungsbereich missbraucht wird, wird sie für alle Registerkarten / Fenster in einer einzelnen Browsersitzung freigegeben, sodass der Endbenutzer nach dem Wechsel zwischen Registerkarten möglicherweise Inkonsistenzen bei der Interaktion mit jeder Ansicht aufweist, was für die Benutzererfahrung schlecht ist. Wenn Sie eine @RequestScoped
Bean für Daten mit Ansichtsbereich missbrauchen, werden Daten mit Ansichtsbereich bei jedem einzelnen (Ajax-) Postback standardmäßig neu initialisiert, was möglicherweise zu nicht funktionierenden Formularen führt ( siehe auch Punkte 4 und 5 hier ). Missbrauch einer @ViewScoped
Bean für Daten im Anforderungs-, Sitzungs- oder Anwendungsbereich und Missbrauch von a@SessionScoped
Bean für anwendungsbezogene Daten wirkt sich nicht auf den Client aus, belegt jedoch unnötigerweise den Serverspeicher und ist einfach ineffizient.
Beachten Sie, dass der Bereich eher nicht aufgrund von Auswirkungen auf die Leistung ausgewählt werden sollte, es sei denn, Sie haben wirklich einen geringen Speicherbedarf und möchten vollständig zustandslos werden. Sie müssen ausschließlich @RequestScoped
Beans verwenden und mit Anforderungsparametern herumspielen, um den Status des Clients beizubehalten. Beachten Sie außerdem, dass es bei einer einzelnen JSF-Seite mit Daten mit unterschiedlichem Gültigkeitsbereich durchaus sinnvoll ist, diese in separaten Backing Beans in einem Bereich abzulegen, der dem Datenbereich entspricht. Die Beans können @ManagedProperty
bei JSF-verwalteten Beans oder @Inject
bei CDI-verwalteten Beans nur über einander zugreifen .
@CustomScoped/NoneScoped/Dependent
Es wird in Ihrer Frage nicht erwähnt, aber (Legacy) JSF unterstützt auch @CustomScoped
und @NoneScoped
, die in der realen Welt selten verwendet werden. Sie @CustomScoped
müssen auf eine benutzerdefinierte Map<K, Bean>
Implementierung in einem breiteren Bereich verweisen, die überschrieben wurde Map#put()
und / oder Map#get()
um eine genauere Kontrolle über die Erstellung und / oder Zerstörung von Beans zu erhalten.
Der JSF @NoneScoped
und der CDI leben @Dependent
grundsätzlich so lange wie eine einzelne EL-Bewertung auf der Bohne. Stellen Sie sich ein Anmeldeformular mit zwei Eingabefeldern vor, die auf eine Bean-Eigenschaft verweisen, und einer Befehlsschaltfläche, die auf eine Bean-Aktion verweist. Mit insgesamt drei EL-Ausdrücken werden dann effektiv drei Instanzen erstellt. Eine mit dem festgelegten Benutzernamen, eine mit dem festgelegten Kennwort und eine, für die die Aktion aufgerufen wird. Normalerweise möchten Sie diesen Bereich nur für Bohnen verwenden, die so lange leben sollen wie die Bohne, in die sie injiziert wird. Wenn also ein @NoneScoped
oder @Dependent
in ein injiziert @SessionScoped
wird, lebt es so lange wie die @SessionScoped
Bohne.
Als letztes unterstützt JSF auch den Flash-Bereich. Es wird von einem kurzen lebenden Cookie unterstützt, das einer Dateneingabe im Sitzungsbereich zugeordnet ist. Vor der Umleitung wird für die HTTP-Antwort ein Cookie mit einem Wert gesetzt, der der Dateneingabe im Sitzungsbereich eindeutig zugeordnet ist. Nach der Umleitung wird das Vorhandensein des Flash-Scope-Cookies überprüft und die mit dem Cookie verknüpfte Dateneingabe aus dem Sitzungsbereich entfernt und in den Anforderungsbereich der umgeleiteten Anforderung gestellt. Schließlich wird das Cookie aus der HTTP-Antwort entfernt. Auf diese Weise hat die umgeleitete Anforderung Zugriff auf Daten mit Anforderungsbereich, die in der ursprünglichen Anforderung vorbereitet wurden.
Dies ist eigentlich nicht als verwalteter Bean-Bereich verfügbar, dh es gibt keine @FlashScoped
. Der Flash-Bereich ist nur als Karte über ExternalContext#getFlash()
in verwalteten Beans und #{flash}
in EL verfügbar .
@FlowScoped
(kein manuelles Starten / Stoppen erforderlich).
ViewAccesscoped
undWindowScoped
ViewScoped
Bean in MyFaces 2.2. Ich habe derzeit ein Problem mit ViewScoped
Bean und Ajax, das ich hier gepostet habe . In MyFaces JIRA gibt es auch eine Diskussion zu diesem Thema.
@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped
Warum unterscheiden sich die von Ihnen beschriebenen Bereiche?
Seit JSF 2.3 sind alle im Paketpaket definierten Bean-Bereiche javax.faces.bean
veraltet, um die Bereiche an CDI auszurichten. Darüber hinaus sind sie nur anwendbar, wenn Ihre Bean @ManagedBean
Anmerkungen verwendet. Wenn Sie JSF-Versionen unter 2.3 verwenden, lesen Sie die Legacy-Antwort am Ende.
Ab JSF 2.3 gibt es folgende Bereiche, die für JSF-Backing-Beans verwendet werden können:
1 .@javax.enterprise.context.ApplicationScoped
: Der Anwendungsbereich bleibt für die gesamte Dauer der Webanwendung bestehen. Dieser Bereich wird von allen Anforderungen und allen Sitzungen gemeinsam genutzt. Dies ist nützlich, wenn Sie Daten für die gesamte Anwendung haben.
2 .@javax.enterprise.context.SessionScoped
: Der Sitzungsbereich bleibt von der Einrichtung einer Sitzung bis zur Beendigung der Sitzung bestehen. Der Sitzungskontext wird von allen Anforderungen gemeinsam genutzt, die in derselben HTTP-Sitzung auftreten. Dies ist nützlich, wenn Sie keine Daten für einen bestimmten Client für eine bestimmte Sitzung speichern möchten.
3 .@javax.enterprise.context.ConversationScoped
: Der Konversationsbereich bleibt als Protokoll erhalten, solange die Bean lebt. Der Bereich bietet zwei Methoden: Conversation.begin()
und Conversation.end()
. Diese Methoden sollten explizit aufgerufen werden, um das Leben einer Bohne zu beginnen oder zu beenden.
4 .@javax.enterprise.context.RequestScoped
: Der Anforderungsumfang ist von kurzer Dauer. Es beginnt, wenn eine HTTP-Anforderung gesendet wird, und endet, nachdem die Antwort an den Client zurückgesendet wurde. Wenn Sie eine verwaltete Bean in den Anforderungsbereich einfügen, wird mit jeder Anforderung eine neue Instanz erstellt. Wenn Sie sich Gedanken über die Kosten für die Speicherung des Sitzungsbereichs machen, sollten Sie den Anforderungsumfang berücksichtigen.
5 .@javax.faces.flow.FlowScoped
: Der Flow-Bereich bleibt so lange bestehen, wie der Flow lebt. Ein Flow kann als enthaltener Satz von Seiten (oder Ansichten) definiert werden, die eine Arbeitseinheit definieren. Der Flow-Bereich war aktiv, solange der Benutzer mit im Flow navigiert.
6 .@javax.faces.view.ViewScoped
: Eine Bean im Ansichtsbereich bleibt bestehen, während dieselbe JSF-Seite erneut angezeigt wird. Sobald der Benutzer zu einer anderen Seite navigiert, verlässt der Bean den Gültigkeitsbereich.
Die folgende Legacy-Antwort gilt für die JSF-Version vor 2.3
Ab JSF 2.x gibt es 4 Bean Scopes:
- @ SessionScoped
- @RequestScoped
- @ApplicationScoped
- @ ViewScoped
Sitzungsbereich: Der Sitzungsbereich bleibt vom Zeitpunkt der Einrichtung einer Sitzung bis zur Beendigung der Sitzung bestehen. Eine Sitzung wird beendet, wenn die Webanwendung die ungültige Methode für das HttpSession-Objekt aufruft oder wenn das Zeitlimit überschritten wird.
RequestScope: Der Anforderungsbereich ist von kurzer Dauer. Es beginnt, wenn eine HTTP-Anforderung gesendet wird, und endet, nachdem die Antwort an den Client zurückgesendet wurde. Wenn Sie eine verwaltete Bean in den Anforderungsbereich einfügen, wird mit jeder Anforderung eine neue Instanz erstellt. Wenn Sie sich Gedanken über die Kosten für die Speicherung des Sitzungsbereichs machen, sollten Sie den Anforderungsumfang berücksichtigen.
ApplicationScope: Der Anwendungsbereich bleibt für die gesamte Dauer der Webanwendung bestehen. Dieser Bereich wird von allen Anforderungen und allen Sitzungen gemeinsam genutzt. Sie fügen verwaltete Beans in den Anwendungsbereich ein, wenn eine einzelne Bean für alle Instanzen einer Webanwendung freigegeben werden soll. Die Bean wird erstellt, wenn sie zum ersten Mal von einem Benutzer der Anwendung angefordert wird, und bleibt so lange aktiv, bis die Webanwendung vom Anwendungsserver entfernt wird.
ViewScope: Der Ansichtsbereich wurde in JSF 2.0 hinzugefügt. Ein Bean im Ansichtsbereich bleibt bestehen, während dieselbe JSF-Seite erneut angezeigt wird. (In der JSF-Spezifikation wird der Begriff "Ansicht" für eine JSF-Seite verwendet.) Sobald der Benutzer zu einer anderen Seite navigiert, verlässt die Bean den Gültigkeitsbereich.
Wählen Sie den Umfang, den Sie basierend auf Ihrer Anforderung haben.
Quelle: Core Java Server Faces 3. Auflage von David Geary & Cay Horstmann [Seite Nr. 51 - 54]
invalidate()
Methode oder ungültige Methode?
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
In Ihrer "Logout Bean" aufgerufen zu werden, ist das, was er meint.