SeamFramework.orgCommunity Documentation

Kapitel 5. Geltungsbereiche und Kontexte

5.1. Typen von Geltungsbereichen
5.2. Eingebaute Geltungsbereiche
5.3. Der Geltungsbereich der Konversation
5.3.1. Konversationsdemarkierung
5.3.2. Konversationsfortpflanzung (Conversation Propagation)
5.3.3. Konversations-Timeout
5.4. Der abhängige Pseudo-Geltungsbereich ("Pseudo-Scope")
5.4.1. Die @New-Annotation

Bis jetzt haben wir ein paar Beispiele von Geltungsbereichtyp-Annotationen gesehen. Der Geltungsbereich eines Web Beans bestimmt den Lebenszyklus der Instanzen des Web Beans. Der Geltungsbereich bestimmt auch, welche Clients sich auf welche Instanzen des Web Beans beziehen. Gemäß der Web Beans Spezifikation bestimmt ein Geltungsbereich:

  • Wann eine neue Instanz eines beliebigen Web Beans mit diesem Geltungsbereich erstellt wird

  • Wenn eine bestehende Instanz eines beliebigen Web Beans mit diesem Geltungsbereich gelöscht wird

  • Welche eingespeisten Referenzen auf eine beliebige Instanz eines Web Beans mit diesem Geltungsbereich verweisen

Wenn wir etwa ein session-begrenztes Web Bean CurrentUser haben, so sehen alle Web Beans, die im Kontext derselben HttpSession aufgerufen werden, dieselbe Instanz von CurrentUser. Diese Instanz wird automatisch erstellt, wenn CurrentUser erstmals in dieser Session benötigt wird und automatisch gelöscht, wenn die Session endet.

Web Beans besitzen ein erweiterbares Kontextmodell. Es ist möglich, neue Geltungsbereiche zu definieren, indem man eine neue Annotation für einen Geltungsbereich-Typ erstellt:

@Retention(RUNTIME)

@Target({TYPE, METHOD})
@ScopeType
public @interface ClusterScoped {}

Natürlich ist dies der einfache Teil des Jobs. Damit dieser Typ von Geltungsbereich von Nutzen ist, müssen wir außerdem ein Context-Objekt definieren, das den Geltungsbereich implementiert! Die Implementierung eines Context ist in der Regel ein sehr technisches Unterfangen, das nur für Framework-Entwicklung vorgesehen ist.

Wir können eine Annotation eines Geltungsbereich-Typs an einer Web Bean Implementierungsklasse anwenden, um den Geltungsbereich des Web Beans festzulegen:

@ClusterScoped

public class SecondLevelCache { ... }

In der Regel verwenden Sie einen der eingebauten Geltungsbereiche der Web Beans.

Web Beans definiert vier eingebaute Geltungsbereiche:

Für eine Web Beans verwendende Webanwendung:

Die Geltungsbereiche von Anfrage und Applikation sind ebenfalls aktiv:

Versucht die Applikation ein Web Bean aufzurufen, das keinen aktiven Kontext besitzt, so wird zur Runtime eine ContextNotActiveException vom Web Bean Manager gemeldet.

Drei der vier eingebauten Geltungsbereiche solltem jedem Java EE Entwickler sehr vertraut sein, daher wollen wir hier nicht weiter auf diese eingehen. Einer der Geltungsbereiche jedoch ist neu.

Der Web Beans Geltungsbereich der Konversation ähnelt dem herkömmlichen Geltungsbereich der Session dahingehend, dass er den mit einem Benutzer des Systems assoziierten Status verwahrt und mehrere Anfragen zum Server umfasst. Anders als für den Geltungsbereich der Session gilt für den Geltungsbereich der Konversation jedoch:

Eine Konversation repräsentiert aus Perspektive des Benutzers eine Aufgabe, eine Arbeitseinheit. Der Konversationskontext enthält den Status dessen, woran der Benutzer gerade arbeitet. Arbeitet der Benutzer gleichzeitig an mehreren Dingen, so existieren mehrere Konversationen.

Der Konversation skontext ist während jeder JSF-Anfrage aktiv. Jedoch werden die meisten Konversationen am Ende der Anfrage gelöscht. Soll eine Konversation den Status über mehrere Anfragen hinweg verwahren, so muss sie explizit zu einer lange laufenden Konversation fortgepflanzt werden.

Web Beans liefert ein eingebautes Web Bean für die Steuerung des Lebenszyklus von Konversationen in einer JSF-Applikation. Dieses Web Bean kann durch Einspeisung erhalten werden:

@Current Conversation Konversation;

Um die mit der aktuellen Anfrage assoziierte Konversation an eine lange laufende Konversation fortzupflanzen, rufen Sie die begin()-Methode vom Applikationscode auf. Um den aktuellen, lange laufenden Konversationskontext für die Löschung am Ende der aktuellen Anfrage zu terminieren, rufen Sie end() auf.

IIm folgenden Beispiel steuert ein konversationsbegrenztes Web Bean die Konversation, mit der es assoziiert ist:

@ConversationScoped @Stateful

public class OrderBuilder {
    private Order order;
    private @Current Conversation conversation;
    private @PersistenceContext(type=EXTENDED) EntityManager em;
    
    @Produces public Order getOrder() {
        return order;
    }
    public Order createOrder() {
        order = new Order();
        conversation.begin();
        return order;
    }
    
    public void addLineItem(Product product, int quantity) {
        order.add( new LineItem(product, quantity) );
    }
    public void saveOrder(Order order) {
        em.persist(order);
        conversation.end();
    }
    
    @Remove
    public void destroy() {}
    
}

Dieses Web Bean ist in der Lage, seinen eigenen Lebenszyklus durch Verwendung der Conversation-API zu steuern. Aber einige andere Web Beans besitzen einen Lebenszyklus, der komplett von einem anderen Objekt abhängt.

Neben den vier eingebauten Geltungsbereichen bieten Web Beans den sogenanntenabhängigen Pseudo-Geltungsbereich. Dies ist der standardmäßige Geltungsbereich für ein Web Bean, das nicht expliziet einen Typ von Geltungsbereich deklariert.

Zum Beispiel besitzt dieses Web Bean den Geltungsbereich-Typ @Dependent:

public class Calculator { ... }

Wenn der Einspeisungspunkt eines Web Bean zu einem abhängigen Web Bean hin aufgelöst wird, so wird jedes Mal, wenn das erste Web Bean instantiiert wird, eine neue Instanz des abhängigen Web Beans erstellt. Instanzen abhängiger Web Beans werden nie von unterschiedlichen Web Beans oder unterschiedlichen Einspeisungspunkten geteilt. Sie sind abhängige Objekte einer anderen Web Bean Instanz.

Abhängige Web Bean Instanzen werden gelöscht, wenn die Instanz von der sie abhängen gelöscht wird.

Web Beans machen es einfach, eine unabhängige Instanz einer Java-Klasse oder eines EJB-Beans zu erhalten, selbst wenn die Klasse oder das EJB-Bean bereits als ein Web Bean mit einem anderen Typ von Geltungsbereich deklariert sind.