关于春天的单身豆

时间:2013-08-13 08:57:19

标签: spring

我正在阅读“Spring in Action”,它说“Spring中的单例bean通常不会维护状态,因为它们通常在多个线程之间共享”,但在我看来,Spring中的bean是一个POJO那么它怎么能不维持状态呢?

4 个答案:

答案 0 :(得分:3)

  

我正在阅读“Spring in Action”,它说的是“单身豆”   Spring经常不维护状态,因为它们通常是共享的   多个线程“,但在我看来,Spring中的bean是一个POJO,所以   怎么不维持状态呢?

是的,Spring / Singleton最好没有状态(当然它可以使用其他Spring / Singletons [也没有状态])所以你可以从不同的线程调用它的方法而不用担心它们会搞乱它的状态(它没有一个:-))。 让我们考虑一个将其中间结果存储在内部堆栈中的计算器,如果两个线程同时尝试计算某些内容会发生什么?

Spring / Singleton是注释的(如果它不是它就像它那样)并且生活在spring环境中,它不是POJO。

如果你想拥有一个具有状态的Spring / Bean,你必须使用范围“prototype”,每当你得到一个bean时,你会得到一个不同的实例。

抱歉英文不好

答案 1 :(得分:2)

本书暗示,由于另一个线程操纵其状态,bean在某个特定时间点可能不值得信任。如果多个线程正在访问bean的同一个实例,则无法确定在使用它之前bean上发生了哪些状态更改。由于Spring默认使用Singletons,因此只有一个bean实例。如果多个线程同时命中bean,则可能存在bean状态的问题。

所以你的错误是bean会保持状态,但是由于其他线程的修改,状态可能不可靠。

答案 2 :(得分:0)

在典型的Web应用程序中,您有多个线程(每个请求一个),并且所有请求都使用相同的bean。在典型的分层应用程序中,他们将使用 Controller ,然后使用服务,然后使用存储库。所有这些豆子都应该是没有任何状态的单身人士。否则,由于并发性,您将遇到错误(例如,一个线程修改单个数据中的数据,而另一个线程执行相同操作)。

我认为你的误解来自于说春天的 bean是POJO 。大多数Spring bean都是无状态bean,我不会将其描述为POJO。

答案 3 :(得分:0)

Spring bean被认为是POJO,因为它不需要遵守特殊要求(实现某些接口,扩展特定类,以某种方式具体,等等)与Spring一起使用。

取决于Spring bean可能需要维护和操作其状态的要求 它还取决于要考虑Spring bean是否应该是单例的要求 如果单个Spring bean正在维护自己的状态,则必须采取适当的安全措施来确保正确的并发访问/修改。

混淆来自企业应用程序中使用的一般模式,其中Spring bean用于实现大量系统逻辑,并支持操作。
在这些场景中,通常它是一个很好的做法,在Spring bean本身没有任何状态,只是包含实际状态的Value Object / Data Transfer对象的扩展。
由于这些Spring bean不会保持自己的状态,因此它们几乎总是被创建为单例。

SomeClassSomeOtherClassSituation都是以下代码中的POJO。
SomeClassSomeOtherClass是Spring bean但Situation不是,这是DTO。

class SomeClass {

    private int x; // not restricted

    public void handleSituation(Situation s) {
        // may or may not use/modify SomeClass state represented by 'x'
        // one approach is to provide all required information through parameters
    }
}

class SomeOtherClass {

    @Autowired
    private SomeClass sc;

    public void process() {
        // gets called from another object

        Situation z = new Situation();
        sc.handleSituation(z);

        // other processing
    }
}

<!-- default scope = singleton -->
<bean id="someClassBean" class="SomeClass"/>

<bean id="someOtherClassBean" class="SomeOtherClass">
    <property name="someClass" ref="someClassBean"/>
</bean>

这与纯OOP略有不同,其中上面的编码类似于以下内容。

class SomeOtherClass {

    public void process() {
        // gets called from another object

        Situation z = new Situation();
        z.handle();

        // other processing
    }
}