Spring Singleton和并发访问

时间:2014-03-05 15:05:06

标签: spring singleton applicationcontext

我的问题是: 让我们假设我有一个春天豆:一个DAO(当然是单身)

所以,当我们有很多用户想要同时使用这个bean时:会发生什么?

,或者

对于每个用户,spring为他实例化一个DAO bean?

==>我们有一个单独的应用程序上下文:spring是否为每个用户创建了一个上下文?

2 个答案:

答案 0 :(得分:3)

  

(当然是单身)

然后它是一个单身人士。 ApplicationContext只会创建一个实例,并将该实例传递到请求的任何位置。

  

对于每个用户,为他弹出[实例化] DAO bean?

不,它将检索并为它们提供相同的DAO实例。

  

==>我们有一个单独的应用程序上下文:spring是否为每个用户创建了一个上下文?

我不确定您对每个用户的含义。 Java应用程序不了解用户。如果您的意思是在多线程应用程序的上下文中,它仍然无关紧要。注入的DAO bean仍然是该单个实例。

如评论中所述,您有责任处理DAO的状态,如果它是可变的,则处理并发访问。使用数据源处理事务(可能使用@Transactional)。

答案 1 :(得分:0)

你不要使用DAO作为Spring bean。 Spring bean(单例范围)更像是一种服务。

假设您有Pizza Dao和PizzaService,您的服务是一个春天的豆子,而披萨不是。

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

您还可以在JunitFoo中实现Runnable并使用不同的线程(您的用户)大量启动someMethod,每个用户都将获得自己的Pizza。 但所有用户都使用相同的pizzaService

由于这个原因,singleton是spring bean的默认范围。您也可以通过从应用程序上下文中获取它来创建Pizza,但在这种情况下,您需要原型,否则所有用户共享相同的披萨

<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