2014-03-05 65 views
0

我的問題是: 讓我們假設我有一個Spring bean:一個DAO一個(這是當然的單身)春辛格爾頓和併發訪問

所以,當我們有很多誰想要使用這個bean的用戶在同一時間:會發生什麼?

或者,

對於每個用戶,spring會爲他實例化一個DAO bean嗎?

==>我們有一個應用程序的單例上下文:春天是否爲每個用戶創建一個上下文?

回答

2

(這是當然的單身)

那麼它是一個單例。 ApplicationContext只會創建一個實例,並在請求的地方傳遞相同的實例。

對於每個用戶,spring [實例化]一個DAO bean給他?

不,它會檢索並給他們相同的DAO實例。

==>我們有一個應用程序的單例上下文:春天是否爲每個用戶創建一個上下文?

我不完全確定你的意思是爲每個用戶。 Java應用程序不知道用戶。如果你的意思是在多線程應用程序的上下文中,它仍然是不相關的。注入的DAO bean仍然是單個實例。

正如評論中所述,如果DAO處於可變狀態並處理併發訪問,則您有責任處理您的DAO狀態。使用數據源處理交易(可能與@Transactional)。

+1

總計與此答案同意。我會補充說你必須在你的DAO中管理事務以處理你的單例實例的多次使用。 – Thomas

+0

@Sotirios Delimanolis:謝謝你的迴應:)。 U說>(這是你的責任來處理你的DAO的狀態):是不是彈簧容器的作用? –

+0

@ zied.j不,Spring將爲DAO管理bean的生命週期。它對這個班的內部一無所知。如果需要的話,它是由線程安全的。 –

0

你不使用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