2017-07-01 94 views
0

我開始使用Spring MVC開發REST API。 我將它部署在一個Tomcat容器中,它的功能就像一個魅力。與Tomcat混淆Spring IoC容器

由於Tomcat負責爲每個請求創建一個新線程(請糾正我,如果我錯了),我想知道Spring如何處理這個來管理IoC(控制反轉)容器。

例子:我有以下服務

@Service 
public class UserService{ 
    private String username; 

    public setUsername(String username){ 
     this.username = username; 
    } 

    public getUsername(){ 
     return this.username; 
    } 
} 

所以基本上Spring將創建這個獨立的,並使其可用於每個人。

如果請求出現並設置「foobar」用戶名,下一個請求(來自不同用戶)的「getUsername」調用是否返回「foobar」? Spring如何管理這種情況?

問候

+3

無論有多少個線程,都有一個實例。春天什麼都不管。與狀態**共享單身**是你通常不應該做的事情。 –

回答

0

默認春豆單作用域,這意味着春天創建bean的實例,並給所有的線程提供相同的實例。由於你的bean是有狀態的(用戶名),所以這個狀態也會被所有的線程共享,Spring在這裏沒有任何魔法。 因此,如果一個線程設置用戶名「xyz」,那麼第二個線程會將其視爲「xyz」。

1

與其他人一樣,默認情況下,Spring創建Singleton範圍bean,以便每個線程都會看到與其他線程相同的類級別狀態。在這種情況下,最好避免在應用程序中維護類級別的狀態,並在方法範圍內通過應用程序傳遞所有必需的數據,從而使它們成爲線程安全的。

但是,讓我們來創建每個線程的bean的新實例,如果你想要的話。你可以用@Scope(「prototype」)註釋你的bean,並且你會得到每個線程的bean實例。默認值是@Scope(「singleton」)。如果您需要它們,還有其他幾個範圍可用。

+0

是否意味着默認情況下我應該將原型範圍放在服務上? – Pascal

+0

是的,如果你確定每次都想要一個新實例並且希望在類/對象中維護狀態,那麼就使用原型範圍。對於大量的併發線程/用戶,您可能會看到對所創建對象的更多實例的性能影響。所以,這是一個需要權衡的折衷方案 - 在內存中存在更多對象實例的潛在性能受到影響,或重新設計應用程序以避免維護對象中的狀態,並恢復爲使用單例。 – MickG

0

docs

只有一個共享一個singleton bean的實例進行管理,並返回用於與ID豆類或ID​​S在一個特定的bean實例bean定義 結果匹配所有 請求春天 容器。換句話說,當你定義一個bean定義並且它作爲一個單例作爲作用域時,Spring IoC容器恰好創建了一個由該bean定義定義的對象的一個​​實例 。此單個實例存儲在此類單例bean的緩存中,並且該命名Bean的所有後續請求和引用都返回緩存的對象 。