2009-03-06 4 views
11

Wir alle wissen, dass es in der Web Tier die Möglichkeit gibt, dass nur eine einzige Instanz eines gegebenen Servlets existiert, die mehrere Anfragen bedient. Dies kann zu Threading-Problemen in Instanzvariablen führen.Ist es sicher, ein EJB als Instanzvariable in ein Servlet zu injizieren?

Meine Frage ist, ist es sicher, ein EJB mit der @ EJB Annotation in ein Servlet als Instanzvariable zu injizieren?

Mein erster Instinkt wäre nein, unter der Annahme, dass die gleiche Instanz des EJB mehrere Anfragen gleichzeitig bedienen würde. Es scheint, dass dies auch der Instinkt einer Reihe anderer Programmierer sein würde: Don't inject to servlets

Allerdings bin ich zu der falschen Schlussfolgerung gesprungen. Was in das Servlet injiziert wird, ist eindeutig ein Proxy. Unter der Haube bedient der Container tatsächlich jede Anfrage mit einer anderen Instanz und behält die Thread-Sicherheit bei? Wie dieses Forum vorschlagen würde: Do inject to servlets

Es scheint eine Menge widersprüchliche Meinungen zu geben. WELCHES IST RICHTIG???

Antwort

3

Ihre Referenz "Nicht in Servlets injizieren" erwähnt nichts über ejbs oder @ejb Annotation. Es spricht über nicht thread-sichere Objekte wie PersistenceContext.

Per EJB-Spezifikation können Sie auf ejbs von verschiedenen Remote-Clients einschließlich Servlets zugreifen (EJB 3.0-Spezifikation (JSR-220) - Abschnitt 3.1). Das Einfügen von ejb mit @ EJB-Annotation ist eine Methode zum Erhalten der EJB-Schnittstelle über die Abhängigkeitsinjektion (Abschnitt 3.4.1), die eine Alternative zum Nachschlagen von ejb-Objekten im JNDI-Namespace darstellt. Es gibt also nichts Besonderes an @EJB Annotation in Bezug auf EJBs erhalten.

Also, basierend auf EJB 3.0 Spec, ist es eine gängige Praxis, ejbs von Servlets mit @ EJB Annotation zu erhalten.

+0

Diese Antwort ist richtig, soweit es geht, aber es behandelt nicht die Thread-Sicherheitsbedenken des OP. Ich glaube, dass die folgende Antwort von inferreddesign die richtige sein sollte. –

+0

Ich denke ein EJB mit @Inject (CDI, JEE 6) wird genauso sicher sein, oder? – marcus

0

Ich denke die einfache Antwort ist, dass Sie nicht garantieren können, dass es sicher ist.

Der Grund dafür ist, dass es in der EJB-Spezifikation nicht explizit heißt, dass EJB-Home-Interfaces Thread-sicher sein müssen. Die Spezifikation beschreibt nur das Verhalten des Serverseitenteils. Was Sie wahrscheinlich finden werden, ist, dass die Client-Skelette tatsächlich Thread-sicher sind, aber Sie müssten schauen, wie sie von der Bibliothek implementiert werden, die Sie verwenden. Der Annotationsteil wird einfach zu einem Service-Locator erweitert, sodass Sie nichts kaufen können.

11

Es ist sicher, ein EJB in ein Servlet als eine Servlet-Instanzvariable zu injizieren, solange das EJB zustandslos ist. Du darfst KEINE Stateful Bean in ein Servlet injizieren.

Sie müssen Ihr EJB stateless implementieren, da es keine Instanzvariable enthält, die selbst einen statusbehafteten Wert enthält (wie Persistence Context). Wenn Sie den Persistenzkontext verwenden müssen, müssen Sie eine Instanz davon in den Methoden des EJB erhalten. Sie können dies tun, indem Sie eine PersistenceContextFactory als EJB-Instanzvariable verwenden und dann eine Instanz des Entity Managers von der Factory in der Methode des EJB erhalten.

Die PersistenceContextFactory ist Thread-sicher, daher kann sie in eine Instanzvariable injiziert werden.

Solange Sie auf die oben genannten Regeln entsprechen, sollte von Thread-sicher sein, eine Stateless Bean in einem Servlet

1

Es ist ein Mischbeutel zu injizieren.

Stateless Session Beans können injiziert werden und sind sicher.Dies liegt daran, dass der Zugriff auf die Methoden vom Container selbst dann serialisiert wird, wenn eine einzelne Instanz eines Stubs verwendet wird.

Ich denke, was inferreddesign sagt, ist nicht wahr. Es spielt keine Rolle, ob die statuslose Session-Bean einen Persistenzkontext verwendet. Nur ein Aufrufer wird jemals gleichzeitig auf eine einzelne Bean-Instanz zugreifen, so dass der Persistenzkontext zwar nicht threadsicher ist, der EJB jedoch den Mehrfachzugriff darauf schützt. Stellen Sie sich vor, dass für jede Session-Bean-Methode das synchronisierte Keyword angewendet wird.

Das Hauptproblem beim Einspritzen eines EJB in ein Servlet denke ich ist die Leistung. Die einzelne Stub-Instanz wird zu einem großen Konfliktfeld, wenn sich mehrere Anfragen in der Warteschlange befinden, während sie darauf warten, dass eine Session-Bean-Methode für sie ausgeführt wird.

+0

Der Stub wird synchronisiert, aber ich erwarte, dass er schnell zu einem der gepoolten EJBs geschickt wird, um die eigentliche Arbeit zu erledigen. Es sei denn, der Stub hält die Sperre während des gesamten Anrufs, was eine sehr schlechte Implementierungswahl wäre ... – marcus

Verwandte Themen