2013-06-21 8 views
29

Ich benutze Frühling von mehr als 6 Monaten. Ich bin nicht in der Lage, diesen zugrunde liegenden Mechanismus im Zusammenhang mit dem folgenden Szenario zu verstehen.Wie behandelt Spring MVC mehrere Benutzer

Ich habe eine Spring Web App. Jetzt habe ich das Modell im Controller autowired. Basierend auf der URL-Übereinstimmung ruft es die entsprechende Methode auf. Alle meine Methoden sind Singleton.

Jetzt, wenn zwei Benutzer die App gleichzeitig öffnen, kann der Frühling sie parallel ausführen und ihnen Ergebnisse geben. Ich habe nicht verstanden, wie es das tun kann. Ich meine, da die Bean Singleton ist, muss entweder gewartet werden, bis die Bean nicht verwendet wird, oder die Daten in der Bean überschrieben werden. Aber der Frühling funktioniert richtig. Kann jemand dieses Verhalten mit einer Analogie erklären?

Auf meine Frage deutlich unter ein Stück Code zu erklären:

Meine Standard-Controller ist einfach:

@Autowired 
private AppModel aModel; 
public AppModel getModel(){ 
    return aModel; 
} 
public void setModel(AppModel aModel){ 
    this.aModel = aModel; 
} 

@RequestMapping(method = RequestMethod.GET) 
public ModelAndView defaultGetter(HttpServletRequest request, 
     HttpServletResponse response) throws Exception { 
    ModelAndView mav = new ModelAndView(getViewName()); 
    mav.addObject("model", aModel); 
    Runtime.getRuntime().gc(); 
    return mav; 
} 

Auch kann jemand mir sagen, wenn zwei Clients die Anwendung wird in zwei separate Modelle öffnen Wird generiert, wenn ich @autowired verwende. Wenn nur eine Modell-Bean für alle Clients existiert, dann sagen Sie, dass die Anfrage von Client 1 gekommen ist und ich 30 Sekunden brauche, um die Ergebnisse zurückzubekommen. Wenn nun der zweite Client die Anfrage in der dritten Sekunde sendet, wird die erste Client-Anfrage überschrieben?

Ich glaube, ich bin verwirrt. Kann jemand klären, wie diese Magie geschieht?

Dank

+3

Sie sollten über [Threads in Anwendungsserver] (http://stackoverflow.com/questions/7457190/how-threads-allocated-to-handle-servlet-request) lesen. – LaurentG

+0

Ich lese die obige Diskussion, aber es ist immer noch nicht klar für mich. Wenn für jede Anfrage ein neuer Thread generiert wird, geschieht dies. Wird neuer thread den ganzen Satz neuer bohnen für ihn kopieren, so dass andere Benutzerdaten diesen Satz nicht überschreiben? Ich weiß nicht, ob ich einen Sinn habe: P – javaMan

+1

die Bohne ist ein Singleton, aber jede Methode bekommt ihre eigene Referenz, pro Thread, auf dem Stapel ... – NimChimpsky

Antwort

25

Jede Web-Anfrage erzeugt einen neuen Thread als explained in this thread.

Spring verwaltet verschiedene Bereiche (Prototyp, Anforderung, Sitzung, Singleton). Wenn zwei gleichzeitige Anforderungen auf eine Singleton-Bean zugreifen, muss die Bean statusfrei sein (oder zumindest synchronisiert sein, um Probleme zu vermeiden). Wenn Sie in einer Bereichsanforderung auf eine Bean zugreifen, wird pro Anforderung eine neue Instanz generiert. Spring verwaltet das für Sie, aber Sie müssen vorsichtig sein und den richtigen Bereich für Ihre Bohnen verwenden. Normalerweise ist Ihr Controller ein Singleton, aber der AppModel muss den Bereich request haben, sonst haben Sie Probleme mit zwei gleichzeitigen Anfragen. This thread could also help you.

Über Ihre letzte Frage "wie diese Magie passiert?" Lautet die Antwort "aspect/proxy". Spring erstellt Proxy-Klassen. Sie können sich vorstellen, dass Spring einen Proxy für Ihre AppModel Klasse erstellt. Sobald Sie versuchen, in der Steuerung darauf zuzugreifen, leitet Spring den Methodenaufruf an die Instanz rechts weiter.

+0

die Antwort war großartig, aber ich habe Zweifel ... "Frühling leitet es an die richtige Instanz weiter. " Wie wird das gemacht? Eine Proxy-Klasse wird erstellt und erstellt sie ein neues Objekt des Proxys für jede erstellte Anfrage? damit die Werte für jede Anfrage erhalten bleiben? –

+2

Alle Beispielprogramme, die diesen Unterschied in jeder Anfrage erläutern, wären hilfreicher. –

Verwandte Themen