通常说只选择那些没有状态的豆子作为单身人士。我是Spring的新手,并在Spring中阅读bean范围。
我的第一个问题是这个STATE对Bean有什么意义?
其次,为什么建议仅使用无状态bean的单例范围?是否有一些与线程安全相关的限制或是否还有其他原因?
答案 0 :(得分:3)
类的任何成员属性都称为其状态。
没有可变状态的类最适合成为Spring(单例)bean。 可变状态是指那些可以在之后分配新值的成员属性。对象已经构建。
具有成员属性(如JpaRespository)的DAO之类的Bean可以被认为具有相当不可变的状态,因为初始化DAO对象后没有人为JpaRespository属性分配新值。
只有没有状态(没有成员属性)或具有不可变状态的bean(成员变量的值在分配值后不会更新)是成为Spring bean的理想候选者。这是因为大多数Spring bean都配置为Singleton bean,并由容器中的多个线程使用。想象一下,如果你有可变状态并且多个线程试图更新单例bean的状态,那么你将永远不会有可预测的结果。
如果你的bean不是Singleton,而是它是一个Prototype bean,那么,那个bean可以有状态,因为这样的bean是根据需要创建和销毁的。
答案 1 :(得分:0)
如果对方法的调用不仅取决于给方法调用的参数,还取决于先前的调用,那么对象(和bean是一个对象)就具有一种状态。
原则上,如果你有任何实例变量,你可能有一个州。唯一的例外是存储在实例(不是static
)变量中的单例(在春季编程中很常见)不计入状态。
使用多线程环境时,单例中的状态可能会产生副作用。例如。一个线程设置状态(例如,连接打开),另一个线程不期望这种状态。然后一个线程可能会失败。
答案 2 :(得分:0)
您希望在哪种对象状态下运行程序。当您设计和编写类时,您不知道客户端是否将其用作单例或原型。容器配置对象。因此,它可能是单例或原型。例如 TransactionAwareDataSourceProxy 编写spring类框架以在protoype或singleton中运行。该类以这样的方式编写,即它可以安全地进行多线程访问。由于所有线程共享的状态通过DI容器与一些setter方法共用。因此,单例配置是在启动时通过容器进行的,其公共值由所有线程或单线程使用。实例变量的设置仅使用一些setter方法进行一次。 例如,在TransactionAwareDataSourceProxy类中, reobtainTransactionalConnections 作为实例变量。
public TransactionAwareDataSourceProxy()
{
reobtainTransactionalConnections = false;
}
public TransactionAwareDataSourceProxy(DataSource targetDataSource)
{
super(targetDataSource);
reobtainTransactionalConnections = false;
}
public void setReobtainTransactionalConnections(boolean reobtainTransactionalConnections)
{
this.reobtainTransactionalConnections = reobtainTransactionalConnections;
}
这些是代码中 reobtainTransactionalConnections 的地方。如果您决定通过DI容器创建此类单例,您可以使用构造函数注入或setter注入设置一次。所以,如果我们创建setter注入然后setReobtainTransactionalConnections将为true或false,并在整个对象生命周期内保持相同。我认为配置对象与容器的优点,可以轻松实现对象状态控制