12

默认情况下,Spring 创建的 Bean 是单例的。它们是线程安全的,因为它们是无状态的。当我们希望 Spring 创建一个有状态的 Bean 时,我们需要使用原型作用域来定义 Bean。我们需要为他们处理线程安全问题。所有无状态 Bean 在被原型 bean 注入时都会被污染。所以,我只是无法想象我们可以在哪里使用原型范围。你能给出一些我们可以/需要使用原型 Spring Bean 的典型场景吗?另外,我们如何才能避免对其他单例 bean 的状态污染?

4

2 回答 2

17

使用原型作用域有很多原因,例如,任何时候你会使用“new”而不是使用单例。每个用户的 bean、每个请求的 bean、唯一 bean 的集合等等。毕竟,在任何不平凡的应用程序中,您使用非单例的次数不远多于单例吗?

单例范围的 bean 不是线程安全的,因为它们是单例的——它们必须写成线程安全的。它们不会神奇地变成线程安全的。bean 的作用域就是它的作用域:它不会使 bean适合特定的作用域——这取决于开发人员。

于 2012-05-13T10:36:12.547 回答
1

我认为原型范围的 bean 可以替代用于创建对象的工厂类。不同之处在于原型 bean 的情况下,spring 将为您节省一些用于依赖注入的代码,并且还会在适当的时候自动代理您的对象进行事务等。

我自己更喜欢工厂方法。我遇到的原型范围的一个合理场景是一个有状态的对象,不同的已知 bean 需要它并且每个都需要自己的副本。在这种情况下,一个专用的工厂类将是多余的,因为我不需要动态创建对象,而只需要在其他 bean 的实例化期间。

于 2012-05-13T20:12:09.200 回答