2013-07-02 104 views
0

一般认为只选择那些没有状态的单身人士。我是Spring的新手,并且在Spring中阅读了关于bean范围的知识。豆的状态是什么意思?

我的第一个疑问是这个STATE对于Bean的实际意义是什么?

其次,为什么建议只使用无状态bean的单例作用域?是否有一些线程安全相关的限制或者是否有其他原因?

+0

在我看来,这个问题更适合程序员。 –

回答

0

如果对方法的调用不仅取决于给予方法调用的参数,而且还取决于以前的调用,则对象(和bean是对象)具有状态。

原则上如果你有任何实例变量你可能有一个状态。唯一的例外是存储在实例(不是static)变量(这在春季编程中很常见)中的单例不计入状态。

当使用多线程环境时,单例状态会产生副作用。例如。一个线程设置状态(例如,打开一个连接),另一个线程不期望这个状态。然后一个线程可能会失败。

+0

所以,我可以说,一个对象的状态不过是它的所有关于实例成员的引用和值。 – Prashant

+0

另外,我从你的答案中得到的答案是,内部的spring不提供任何单线程bean的线程安全支持。真的吗? – Prashant

+0

状态存储在实例变量中。只要你没有实例变量,很可能你没有状态(有一些例外,例如你也可以在'static'变量中存储状态,但这在大多数情况下不是你想要的)。 –

0

你想在哪个对象状态下运行你的程序。当你设计和编写你的类时,你不知道客户是否使用它作为单例或原型。容器配置对象。因此,它可能是单例或原型。例如TransactionAwareDataSourceProxy 弹簧框架的类被编写为运行在原型或单例中。该类以多线程访问安全的方式编写。由于所有线程共享的状态通过DI容器与一些setter方法共同使用,因此,配置为singleton是在启动时通过容器进行的,其公共值由所有线程或单个线程使用。实例变量只用一些setter方法制作一次。 例如在类TransactionAwareDataSourceProxy中有reobtainTransactionalConnections作为实例变量。

public TransactionAwareDataSourceProxy() 
    { 
     reobtainTransactionalConnections = false; 
    } 

    public TransactionAwareDataSourceProxy(DataSource targetDataSource) 
    { 
     super(targetDataSource); 
     reobtainTransactionalConnections = false; 
    } 
    public void setReobtainTransactionalConnections(boolean reobtainTransactionalConnections) 
    { 
     this.reobtainTransactionalConnections = reobtainTransactionalConnections; 
    } 

这些是。如果你决定要通过你要么构造函数注入或setter injection.So设置一次,如果我们把setter注入DI容器此类单reobtainTransactionalConnections是iniatialized代码中的地方那么setReobtainTransactionalConnections将是真或假,并在整个对象的生命周期内保持不变。我认为配置容器的对象的优点,对象状态控制可以很容易地做出

1

类的任何成员属性被称为其状态。

没有可变状态的类最适合成为Spring(单例)bean。可变状态引用了在构造对象之后可以为其分配新值的成员属性。

像DAO这样具有成员属性(如JpaRespository)的bean可以被认为具有相当不可变的状态,因为一旦DAO对象被初始化,没有人为JpaRespository属性赋予新的值。

只有没有状态(没有成员属性)或具有不可变状态(成员变量的值一旦被赋值后就不更新)的bean是成为Spring bean的理想候选者。这是因为大多数Spring bean都被配置为Singleton bean,并被容器中的多个线程使用。试想一下,如果你有可变状态,并且多个线程试图更新singleton bean的状态,那么你永远不会有可预测的结果。

如果你的bean不是Singleton,而是它是一个Prototype bean,那么这个bean可以拥有状态,因为这些bean是根据需要创建和销毁的。

相关问题