我的問題是: 讓我們假設我有一個Spring bean:一個DAO一個(這是當然的單身)春辛格爾頓和併發訪問
所以,當我們有很多誰想要使用這個bean的用戶在同一時間:會發生什麼?
或者,
對於每個用戶,spring會爲他實例化一個DAO bean嗎?
==>我們有一個應用程序的單例上下文:春天是否爲每個用戶創建一個上下文?
我的問題是: 讓我們假設我有一個Spring bean:一個DAO一個(這是當然的單身)春辛格爾頓和併發訪問
所以,當我們有很多誰想要使用這個bean的用戶在同一時間:會發生什麼?
或者,
對於每個用戶,spring會爲他實例化一個DAO bean嗎?
==>我們有一個應用程序的單例上下文:春天是否爲每個用戶創建一個上下文?
(這是當然的單身)
那麼它是一個單例。 ApplicationContext
只會創建一個實例,並在請求的地方傳遞相同的實例。
對於每個用戶,spring [實例化]一個DAO bean給他?
不,它會檢索並給他們相同的DAO
實例。
==>我們有一個應用程序的單例上下文:春天是否爲每個用戶創建一個上下文?
我不完全確定你的意思是爲每個用戶。 Java應用程序不知道用戶。如果你的意思是在多線程應用程序的上下文中,它仍然是不相關的。注入的DAO
bean仍然是單個實例。
正如評論中所述,如果DAO處於可變狀態並處理併發訪問,則您有責任處理您的DAO狀態。使用數據源處理交易(可能與@Transactional
)。
你不使用DAO作爲Spring bean。 Spring bean(單例作用域)更像是一種服務。可以說你有比薩餅和披薩服務,你的服務是春豆,而比薩餅不是。
class Pizza {
Set ingredients = ... ;
public Pizza(Set s) {
...
}
private addIngredient(Object o) {
set.add...
}
}
@Service
class PizzaService {
private Pizza createPizza(..){
Pizza p = new Pizza();
....
return pizza;
}
private void persistPizza(Pizza pizza){
..save to db..
}
}
測試服務:
class JunitFoo{
@Autowired private PizzaService service;
@Test
someMethod(){
Pizza p = service.createPizza();
p.addIngredient(cheese)
service.persistPizza(p);
}
}
您也可以實現Runnable接口JunitFoo和發射的someMethod了大量的時間與型動物線程(你的用戶),每個用戶都會有自己的比薩。 但所有用戶使用相同的pizzaService。
由於這個原因,singleton是spring bean的默認範圍。您也可以從你的應用程序上下文獲取它創建一個比薩,但在這種情況下,你需要原型,否則所有用戶都共享同一個比薩餅
<bean id="pizza" class="foo.Pizza" scope="prototype" >
<default set of pizza stuff>
</bean>
如果你這樣做的,你PizzaService看起來是這樣的:
@Service
class PizzaService {
@Autowired private ApplicationContext context;
private Pizza createPizza(..){
return (Pizza) context.getBean("pizza");
}
private void persistPizza(Pizza pizza){
..save to db..
}
}
本主題是方式來大到在一個單一的職位,我希望我可以幫助和提高你的理解。 Please also check the spring documantation about bean scopes。
總計與此答案同意。我會補充說你必須在你的DAO中管理事務以處理你的單例實例的多次使用。 – Thomas
@Sotirios Delimanolis:謝謝你的迴應:)。 U說>(這是你的責任來處理你的DAO的狀態):是不是彈簧容器的作用? –
@ zied.j不,Spring將爲DAO管理bean的生命週期。它對這個班的內部一無所知。如果需要的話,它是由線程安全的。 –