2013-06-21 91 views
29

我使用6個月以上的spring。我無法理解與以下情況相關的這種基礎機制。Spring MVC如何處理多個用戶

我有一個春天的web應用程序。現在我在控制器中自動裝配模型。基於url匹配,它調用相應的方法。我所有的方法都是單身。

現在,當兩個用戶同時打開應用程序時,彈簧可以並行運行它們並向它們提供結果。我不明白它如何做到這一點。我的意思是,因爲bean是單例,它必須等待,直到bean未被使用或覆蓋bean中的數據。但春天工作正常。有人能用一些類比來解釋這種行爲嗎?

要明顯低於解釋我的問題是一段代碼:

我的默認控制器是簡單的:

@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; 
} 

也可以有一個人告訴我,當兩個客戶端打開的應用程序將兩個單獨的模型當我使用@autowired時生成。如果只有一個模型bean存在於所有客戶端中,那麼就說來自客戶端1的請求進來了,我花了30秒纔得到結果。現在,如果第二個客戶端在3秒內發送請求,那麼第一個客戶端請求會被覆蓋嗎?

我覺得我感到困惑。有人能澄清這種魔法是如何發生的嗎?

感謝

+3

您應該閱讀[應用程序服務器中的線程](http://stackoverflow.com/questions/7457190/how-threads-allocated-to-handle-servlet-request)。 – LaurentG

+0

我讀過上面的討論,但仍然不清楚。如果發生這種情況,每個請求都會生成一個新線程。新線程是否會爲其複製一組新的bean,以便其他用戶的數據不會寫入此集?我不知道我是否有任何意義:P – javaMan

+1

這個bean是單例,但是每個方法都得到它自己的引用,每個線程,在棧上... – NimChimpsky

回答

25

每個Web請求生成一個新的線程爲explained in this thread

Spring管理不同的作用域(原型,請求,會話,單例)。如果兩個同時發生的請求訪問一個單身bean,那麼這個bean必須是無狀態的(或至少同步以避免問題)。如果你在範圍請求中訪問一個bean,那麼每個請求都會產生一個新的實例。 Spring爲你管理這個,但你必須小心,併爲你的bean使用正確的範圍。通常情況下,您的控制器是一個單身人士,但AppModel必須是範圍request,否則您將有兩個同時請求的問題。 This thread could also help you

關於你最後一個問題「這個魔法是怎麼發生的?」,答案是「方面/代理」。 Spring創建代理類。你可以想象Spring會爲你的AppModel類創建一個代理。只要您嘗試在控制器中訪問它,Spring就會將該方法調用轉發給右側的實例。

+0

答案很好,但是我有疑問......「Spring將其轉發給正確的實例。「這是如何完成的?代理類是否被創建,併爲每個產生的請求創建代理的新對象?以便每個請求的值保持不變? –

+2

任何用於解釋每個請求中的差異的示例程序都會更有幫助。 –