2012-11-29 8 views
5

Ich denke, ich habe ein grundlegendes Verständnis Problem hier und ich hoffe, dass jemand mir das erklären kann.JAVA EE 6 teilen Instanzen zwischen Stateful EJBs

Können sagen, wir haben eine Stateful EJB_A und eine Stateful EJB_B und sessionscoped ManagedbeanA:

@Stateful 
@LocalBean 
public class EJB_A { 
} 

@Stateful 
@LocalBean 
public class EJB_B { 
    @EJB 
    EJB_A ejb; 
} 
@ManagedBean 
@SessionScoped 
public class ManagedBeanA { 
    @EJB 
    EJB_A ejb; 
} 

Im ManagedBeanA, die EJB_A erstellt wird. Wenn ich nun das EJB_B verwende, welches das EJB_A als Eigenschaft hat, wird eine neue Instanz des EJB_A innerhalb des EJB_B erzeugt. Es ist nicht dieselbe Instanz von EJB_A, die zuvor in ManagedBeanA erstellt wurde.

Ich verstehe das nicht, weil ich dachte, der ganze Punkt von Stateful EJBs ist, dass für jeden Client nur eine Instanz erstellt und vom EJB-Container geteilt und verwaltet wird. Kann mir bitte jemand das erklären? Und erklären Sie bitte auch, wie ich erreichen kann, dass die gleiche Instanz eines EJB von mehreren anderen EJBs geteilt wird?

Danke

+0

Wenn Sie sagen " Jetzt, wenn ich das EJB_B benutze: "Was meinst du damit? Wie haben Sie festgestellt, dass es sich nicht um dieselbe Instanz handelt? –

+0

Wenn ich EJB_B instianziiere und die Eigenschaften (z. B. eine Zeichenfolgeneigenschaft) von EJB_A ate, unterscheiden sich die Eigenschaften der EJB_A-Bean von den Eigenschaften der EJB_A, die von der verwalteten Bean instanziiert wurden. – user1727072

+0

Wo "instanziieren" Sie EJB_B; in einem anderen ManagedBean oder einem Java-Client (Remote-Lookup)? –

Antwort

9

Ja, Sie verschiedene Konzepte gemischt, und zu unterschiedlich APIS ... Ich würde eher @Inject über @EJB verwenden und den Umfang der injizierten Instanz angeben ..

@Stateful 
@LocalBean 
public class EJB_A { 
} 

@Stateful 
@LocalBean 
public class EJB_B { 
    @Inject @SessionScoped 
    EJB_A ejb; 
} 
@ManagedBean 
@SessionScoped 
public class ManagedBeanA { 
    @Inject @SessionScoped 
    EJB_A ejb; 
} 
+0

können Sie erklären, warum ich @Inject anstelle von @EJB verwenden sollte? – user1727072

+1

Nun, eine eingehende Diskussion des Themas ist unter: [link] http://www.seamframework.org/107780.lace Grundsätzlich der Diskriminanzfaktor ist, dass '@ Inject' ist immer bewusst, den Umfang der injected object und dass Sie sicher sind, dass es sich bei der injizierten Instanz um eine verwaltete Instanz handelt (dadurch werden lästige Remotebohnen-Serialisierungsprobleme verhindert). Mit '@ Inject' erhalten Sie ein (manchmal proxied) verwaltetes Objekt, mit '@ EJB' erhalten Sie eine Ressource, nicht viel anders als ein einfacher JNDI Lookup –

+0

danke das macht viel für mich :)! – user1727072

1

Ich glaube, ich zwei Dinge verwechselt - @SessionScoped und @Stateful.

Die @Stateful Annotation bedeutet nicht, dass nur eine Instanz pro Client erstellt wird. Es bedeutet nur, dass das @ Stateful-EJB nur zu EINEM Client gehört, während ein @ Stateless EJB von mehreren Clients gemeinsam genutzt werden kann.

So hat ein @ Stateful-EJB eine N: 1-Relation (N @ Stateful-EJBs gehören genau zu einem Client) und eine @ Stateless-EJB hat eine N: M-Relation (N @ Stateless-EJBS gehört zu M-Clients). Dies bedeutet, dass eine EJB-Instanz nicht von mehreren anderen EJBs gemeinsam genutzt werden kann, indem Sie einfach die @ EJB-Annotation für @Stateful EJBs verwenden.

Es scheint ein @ Sessionscoped-Managedbean auf der anderen Seite wird nur einmal pro Client erstellt.

Habe ich das richtig verstanden?

2

Ich habe gerade etwas gelesen here.

Der Grund dafür ist, dass jeder Lookup() einer EJB 3.0 Stateful Session Bean Remote- oder Local Business Interface führt zur Schaffung einer neuen Bohne Identität. Jeder von der Suche zurückgegebene Verweis verweist auf eine andere Stateful-Session-Bean . Es liegt an dem Anrufer, zu bestimmen, wie er den Zugriff auf diese Referenz verwalten möchte. In der Regel speichert eine Webanwendung die Referenz in einem HttpSession- oder -Anwendungs-weiten Bereich (ServletContext) für den nachfolgenden Zugriff.

Und:

Sie in Ihrem Fall nicht vergessen, dass wir mit zwei Arten von Sitzungen zu tun hat: die Bean-Sitzung und der Web-Session. Ersteres stellt sicher, dass, sobald Sie eine stateful Bean anfordern Identität bleibt die gleiche über die Benutzersitzung. Aber wenn Sie Letzteres verwenden, haben Sie eine Web-Sitzung unter oben in der Bean-Sitzung. Um sicherzustellen, dass Sie auf dieselbe Bean von 2 verschiedenen JSPs zugreifen (oder wenn Sie einen Reload durchführen), müssen Sie die Bean-Identität im Web-Session-Bereich speichern.

So haben Sie eigentlich recht.Wenn Sie Ihre Instanz verwenden möchten, müssen Sie die ManagedBean verwenden, um sie an anderer Stelle abzurufen, da die EJB-Instanz diesem Sitzungskontext zugeordnet ist. Also, wenn Sie es vereinfachen wollten und sicher sein müssen, dass das EJB nur einmal pro Sitzung existiert, verwenden Sie CDI und kommentieren Sie das EJB selbst zusätzlich mit @javax.enterprise.context.SessionScoped; als du sicher sein kannst.

+0

danke sehr hilfreich! – user1727072