Mir ist aufgefallen, dass es verschiedene Bereiche für Bohnen gibt:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Was ist der Zweck der einzelnen Maßnahmen? Wie wähle ich ein geeignetes Zielfernrohr für meine Bohne aus?
Mir ist aufgefallen, dass es verschiedene Bereiche für Bohnen gibt:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Was ist der Zweck der einzelnen Maßnahmen? Wie wähle ich ein geeignetes Zielfernrohr für meine Bohne aus?
Sie stellt den Geltungsbereich (die Lebensdauer) der Bean dar. Dies ist einfacher zu verstehen, wenn Sie mit der Funktionsweise einer einfachen Servlet-Webanwendung vertraut sind: Wie funktionieren Servlets? Instanziierung, Sitzungen, gemeinsame Variablen und Multithreading .
@Request/View/Flow/Session/ApplicationScoped
A @RequestScoped
Bean lebt so lange wie ein einzelner HTTP-Anfrage-Antwort-Zyklus (beachten Sie, dass eine Ajax-Anfrage auch als eine einzelne HTTP-Anfrage zählt). A @ViewScoped
Bean lebt, solange Sie mit der gleichen JSF-Ansicht durch Postbacks interagieren, die Aktionsmethoden aufrufen, die null
/ void
ohne jegliche Navigation/Weiterleitung. A @FlowScoped
Bean lebt so lange, wie Sie durch die angegebene Sammlung von Ansichten navigieren, die in der Flow-Konfigurationsdatei registriert sind. A @SessionScoped
bean lebt so lange wie die bestehende HTTP-Sitzung. Eine @ApplicationScoped
Bean lebt so lange, wie die Webanwendung läuft. Beachten Sie, dass das CDI @Model
ist im Grunde ein Stereotyp pour @Named @RequestScoped
Es gelten also dieselben Regeln.
Welcher Bereich zu wählen ist, hängt allein von den Daten (dem Zustand) ab, die die Bean enthält und darstellt. verwenden @RequestScoped
für einfache und Nicht-AJAX-Formulare/Präsentationen. verwenden @ViewScoped
für umfangreiche Ajax-fähige dynamische Ansichten (Ajax-gestützte Validierung, Rendering, Dialoge usw.). verwenden @FlowScoped
für das "Assistenten"-Muster ("Fragebogen") zur Erfassung von Eingabedaten über mehrere Seiten hinweg. Verwenden Sie @SessionScoped
für kundenspezifische Daten, z. B. den angemeldeten Benutzer und die Benutzereinstellungen (Sprache usw.). Verwenden Sie @ApplicationScoped
für anwendungsweite Daten/Konstanten, wie Dropdown-Listen, die für alle gleich sind, oder Managed Beans ohne Instanzvariablen und nur mit Methoden.
Der Missbrauch eines @ApplicationScoped
bean für session/view/request scoped data würde dazu führen, dass alle Benutzer sie gemeinsam nutzen können, so dass jeder die Daten der anderen sehen kann, was schlichtweg falsch ist. Der Missbrauch einer @SessionScoped
bean für view/request scoped data würde dazu führen, dass sie von allen Tabs/Fenstern in einer einzigen Browsersitzung gemeinsam genutzt werden, so dass der Endbenutzer Inkonsistenzen bei der Interaktion mit jeder View nach dem Wechsel zwischen Tabs erleben kann, was schlecht für die Benutzererfahrung ist. Der Missbrauch einer @RequestScoped
Bean für ansichtsspezifische Daten würde dazu führen, dass ansichtsspezifische Daten bei jedem einzelnen (Ajax-)Postback auf den Standardwert zurückgesetzt werden, was möglicherweise zu nicht funktionierenden Formularen führt ( siehe auch die Punkte 4 und 5 hier ). Der Missbrauch einer @ViewScoped
Bean für anfrage-, sitzungs- oder anwendungsspezifische Daten, und der Missbrauch einer @SessionScoped
bean für anwendungsspezifische Daten wirkt sich nicht auf den Client aus, beansprucht aber unnötig Serverspeicher und ist schlichtweg ineffizient.
Beachten Sie, dass der Geltungsbereich nicht aufgrund von Leistungseinflüssen gewählt werden sollte, es sei denn, Sie wirklich einen geringen Speicherbedarf haben und vollständig zustandslos sein wollen, müssen Sie ausschließlich @RequestScoped
Beans und fummeln an den Anfrageparametern herum, um den Zustand des Clients zu erhalten. Beachten Sie auch, dass es, wenn Sie eine einzelne JSF-Seite mit unterschiedlich skalierten Daten haben, durchaus zulässig ist, diese in separate Backing-Beans in einem Bereich zu legen, der dem Bereich der Daten entspricht. Die Beans können einfach auf einander zugreifen über @ManagedProperty
im Falle von JSF-verwalteten Beans oder @Inject
im Falle von CDI-verwalteten Bohnen.
@CustomScoped/NoneScoped/Dependent
Es ist nicht in Ihrer Frage erwähnt, aber (Legacy) JSF unterstützt auch @CustomScoped
y @NoneScoped
die in der realen Welt selten verwendet werden. Die @CustomScoped
muss eine benutzerdefinierte Map<K, Bean>
Umsetzung in einem breiteren Rahmen, der sich über Map#put()
und/oder Map#get()
um eine feinere Kontrolle über die Erstellung und/oder Zerstörung von Bohnen zu erhalten.
Der JSF @NoneScoped
und CDI @Dependent
lebt im Grunde so lange wie eine einzige EL-Auswertung 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, also mit insgesamt drei EL-Ausdrücken, dann werden effektiv drei Instanzen erstellt. Eine mit dem eingestellten Benutzernamen, eine mit dem eingestellten Passwort und eine, auf der die Aktion aufgerufen wird. Normalerweise sollten Sie diesen Bereich nur für Beans verwenden, die so lange leben sollen wie die Bean, in die sie injiziert werden. Wenn also eine @NoneScoped
o @Dependent
wird in eine @SessionScoped
dann wird es so lange leben, wie die @SessionScoped
Bohne.
Als letztes unterstützt JSF auch den Flash-Bereich. Er wird durch ein kurzes, lebendiges Cookie unterstützt, das mit einem Dateneintrag im Sitzungsbereich verbunden ist. Vor der Weiterleitung wird in der HTTP-Antwort ein Cookie mit einem Wert gesetzt, der eindeutig mit dem Dateneintrag im Sitzungsbereich verknüpft ist. Nach der Weiterleitung wird das Vorhandensein des Flash-Scope-Cookies überprüft, und der mit dem Cookie verbundene Dateneintrag wird aus dem Session-Scope entfernt und in den Request-Scope der weitergeleiteten Anfrage aufgenommen. Schließlich wird das Cookie aus der HTTP-Antwort entfernt. Auf diese Weise hat die umgeleitete Anfrage Zugriff auf Daten im Anforderungsbereich, die in der ursprünglichen Anfrage vorbereitet wurden.
Dies ist eigentlich nicht als verwalteter Bean-Bereich verfügbar, d.h. es gibt kein solches Ding wie @FlashScoped
. Der Blitzbereich ist nur als Karte verfügbar über ExternalContext#getFlash()
in verwalteten Bohnen und #{flash}
in EL.
Seit JSF 2.3 sind alle Bean-Scopes, die im Paket javax.faces.bean
wurden veraltet, um die Geltungsbereiche an CDI anzugleichen. Außerdem sind sie nur anwendbar, wenn Ihre Bean die @ManagedBean
Bemerkung. Wenn Sie JSF-Versionen unter 2.3 verwenden, lesen Sie bitte die Antwort auf die Frage am Ende.
Ab JSF 2.3 gibt es Scopes, die auf 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 Anfragen und allen Sitzungen gemeinsam genutzt. Dies ist nützlich, wenn Sie Daten für die gesamte Anwendung haben.
2. @javax.enterprise.context.SessionScoped
: Der Sitzungsumfang bleibt ab dem Zeitpunkt des Sitzungsaufbaus bis zur Beendigung der Sitzung bestehen. Der Sitzungskontext wird von allen Anfragen, die in derselben HTTP-Sitzung auftreten, gemeinsam genutzt. Dies ist nützlich, wenn Sie Daten für einen bestimmten Client für eine bestimmte Sitzung speichern möchten.
3. @javax.enterprise.context.ConversationScoped
: Der Konversationsbereich bleibt so lange bestehen, wie die Bean lebt. Der Bereich bietet 2 Methoden: Conversation.begin()
y Conversation.end()
. Diese Methoden sollten explizit aufgerufen werden, entweder um das Leben einer Bean zu beginnen oder zu beenden.
4. @javax.enterprise.context.RequestScoped
: Der Anfragebereich ist von kurzer Dauer. Er beginnt, wenn eine HTTP-Anfrage übermittelt wird und endet, nachdem die Antwort an den Client zurückgesendet wurde. Wenn Sie eine verwaltete Bean in den Anfragebereich stellen, wird bei jeder Anfrage eine neue Instanz erstellt. Es lohnt sich, den Anfragebereich in Betracht zu ziehen, wenn Sie sich über die Kosten für die Speicherung des Sitzungsbereichs Gedanken machen.
5. @javax.faces.flow.FlowScoped
: Der Flow-Bereich bleibt bestehen, solange der Flow lebt. Ein Flow kann als eine Gruppe von Seiten (oder Views) definiert werden, die eine Arbeitseinheit definieren. Der Flow-Bereich ist aktiv, solange der Benutzer in dem 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, geht die Bean aus dem Geltungsbereich heraus.
Die folgende Legacy-Antwort gilt für JSF-Versionen vor 2.3
Ab JSF 2.x gibt es 4 Bean Scopes:
- @SessionScoped
- @RequestScoped
- @ApplicationScoped
- @ViewScoped
Umfang der Sitzung: Der Sitzungsumfang bleibt ab dem Zeitpunkt des Sitzungsaufbaus bis zur Beendigung der Sitzung bestehen. Eine Sitzung wird beendet wenn die Webanwendung die invalidate-Methode für das HttpSession-Objekts aufruft oder ein Timeout eintritt.
AnfrageUmfang: Der Umfang der Anfrage ist von kurzer Dauer. Er beginnt, wenn eine HTTP-Anfrage gestellt wird und endet, nachdem die Antwort an den Client zurückgeschickt wurde. Wenn Sie eine verwaltete Bean im Anfragebereich platzieren, wird eine neue Instanz mit jeder Anfrage erstellt. Es lohnt sich, den Request Bereich in Betracht zu ziehen, wenn Sie sich über die Kosten für die Speicherung im Sitzungsbereich Gedanken machen.
Anwendungsbereich: Der Anwendungsbereich bleibt für die gesamte Dauer der Webanwendung bestehen. Dieser Bereich wird von allen Anfragen und alle Sitzungen geteilt. Sie platzieren verwaltete Beans in den Anwendungsbereich, wenn eine einzelne Bean von allen Instanzen einer Instanzen einer Webanwendung gemeinsam genutzt werden soll. Die Bean wird konstruiert, wenn sie von einem Benutzer der Anwendung angefordert wird, und sie bleibt aktiv bis die Webanwendung vom Anwendungsserver entfernt wird.
AnsichtScope: Der Ansichtsbereich wurde in JSF 2.0 hinzugefügt. Eine Bean im Ansichtsbereich bleibt bestehen, während die gleiche JSF-Seite erneut angezeigt wird. (Die JSF Spezifikation verwendet den Begriff View für eine JSF-Seite.) Sobald der Benutzer zu einer anderen Seite navigiert, geht die Bean aus dem Geltungsbereich heraus.
Wählen Sie den Bereich, der Ihren Anforderungen entspricht.
Quelle: Core Java Server Faces 3. Auflage von David Geary & Cay Horstmann [Seite Nr. 51 - 54]
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.