2012-03-26 9 views
7

bin ich ein wenig verwirrt darüber, welche in der folgenden Situation verwenden:Verständnis cdi Instanz <> und .get() vs @Inject

das Servlet Angenommen, erstellt eine Anwendung, die der HTTP-Sitzung des Benutzers behandelt, und die Anwendung ist dies:

public class Application extends AbstractHTTPApplication { 

@Inject 
private Instance<MainView> mainView; 

public void setupApplication() { 
    this.setView(mainView.get()); 
} 

Später habe ich eine @SessionScoped Bohne SSB, die ich will in jedem Benutzer-Bean injizieren:

@SessionScoped 
public class SSB {} 

Jetzt Wenn ich eine regelmäßige @Inject SSB ssb; als ein Feld in MainView versucht, ich habe keine neue SSB für jeden Benutzer erhalten:

public class MainView { 

@Inject 
private SSB usersSSB; 

    public someMethod() { 
     usersSSB.doSomething(); 
     System.identityHashCode(usersSSB); 
    } 
} 

Testing mit zwei Benutzern, erhalte ich die gleiche Instanz usersSSB in beiden Sitzungen des Benutzers. Ich dachte nicht, dass das möglich war ... Ich dachte, da SSB SessionScoped ist, wird jeder Benutzersitzung ein neues gegeben, und egal wo es ist @Inject ed es dass Benutzer SSB.

Stattdessen habe ich versucht:

public class MainView { 

@Inject 
private Instance<SSB> usersSSB; 

    public someMethod() { 
     usersSSB.get().doSomething(); 
     System.identityHashCode(usersSSB.get()); 
    } 
} 

Jetzt meldet er einen anderen usersSSB für jeden Benutzer, endlich.

Was passiert hier? Wenn ich in der Sitzung jedes Benutzers später usersSSB.get() rufe, wird die usersSSB.get()die gleiche Bohne zurückgeben für das gleiche Benutzer jedes Mal?

Ich laufe auf Glassfish 3.1.2.

Einige Mehr Infos

Die Anwendungsklasse in die Servlet auf einem neuen HttpServletRequest injiziert wird:

public abstract class AbstractCdiApplicationServlet extends 
    AbstractApplicationServlet { 
@Inject 
protected Instance<ApplicationWrapper> wrapper; 

@Override 
protected Application getNewApplication(HttpServletRequest request) 
     throws ServletException { 
    return wrapper.get().getApplication(); 
} 
...etc etc 

Und die ApplicationWrapper ist ein SessionScoped Bohne:

@SuppressWarnings("serial") 
@SessionScoped 
public class ApplicationWrapper implements Serializable { 
@Inject 
private AbstractCdiApplication application; 

public AbstractCdiApplication getApplication() { 
    return application; 
} 
} 

Doesn Das bedeutet, dass @Inject SSB usersSSB irgendwo in MainView (oder beliebiges Objekt in der Sitzung dieses Benutzers) sollte mir die session-scoped Bean dieses Benutzers geben, und immer dieselbe Session-Scoped-Bean für jede Benutzersitzung? Bedeutung - unterschiedliche usersSSB für verschiedene Benutzer, da jeder Benutzer eine andere Sitzung hat.

Schließlich ist die Application selbst eine SessionScoped Bean, in die HTTP-Sitzung des Benutzers durch die getNewApplication-Methode des Servlets injiziert und angefügt? Ich meine, es ist das Application-Objekt, das die MainView-Klasse injiziert und anhängt, oder? Das bedeutet, MainView ist eine sitzungsspezifische Bean, oder?

Ich versuche nur herauszufinden, wie das alles funktioniert, denke ich. Danke für die Hilfe!

+0

Das ist sehr merkwürdig. Haben Sie dieses Muster zum Testen zur Verfügung? – LightGuard

+0

Um ehrlich zu sein, habe ich keine solide Handhabe dabei, um einen einfachen Testfall zu erstellen ... Gibt es einen funktionierenden Maven-Archetyp, der Sie mit einem http-Servlet startet, das für jede neue Sitzung eine Anwendung erstellt? Ich könnte damit ein Testprojekt erstellen und es veröffentlichen. –

Antwort

5

Dies geschieht, weil ‚@Inject Instanz <>‘ im Gegensatz zu

‚@Inject‘ erhalten dynamisch Wenn Sie ‚@Inject‘ in ApplicationScoped Bohne tun dann nur einmal erhalten Injektion wird so in ApplicationScoped Bohne wird dies gleiche Referenz für alle Benutzer

Wenn Sie .get() auf ‚@Inject Instanz <>‘ rufen dann SSB Referenz wird dynamisch jedes Mal erhalten, wenn Sie anrufen .get()

Mehr über Injektion kann man lesen hier: http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html

+0

Ich habe weitere Informationen hinzugefügt, die von Ihrem Kommentar, Krzusztof gespornt wurden. Sollte '@Inject' in eine SessionScoped-Bean (MainView) nicht immer dasselbe Objekt für diesen Benutzer geben? Und sollte das '@ Inject' einem anderen Benutzer ein * anderes * Objekt geben, da sie sich in einer anderen Sitzung befinden? –

+1

Was Sie tatsächlich erhalten, ist ein Proxy, der jedes Mal nach der richtigen Ressource sucht. – LightGuard

+1

Sollte @Inject nicht auch der richtigen Ressource einen Proxy geben? –