为什么Spring bean是单例范围?

use*_*481 6 spring

我正在与Hibernet和Spring合作,这很好......但我有些疑惑

1)为什么弹簧范围默认是单身?有什么理由吗?

2)我可以在Hibernate实体中编写final varible吗?示例:

@Entity
public class Emp {
  @Id
  private Long id;
  final private String panNo;
}
Run Code Online (Sandbox Code Playgroud)

我可以像上面那样写

3)静态变量可以Seracizable?

Chr*_*ang 17

如果你仔细看看Spring,你会发现Spring可以帮助你编写服务,而不是数据对象.使用Spring,您仍然需要管理自己的域对象,可能是关系数据对象或直接POJO,并将它们作为输入传递给Spring托管服务,存储库和控制器等.

因此,考虑到这一点,应该清楚为什么Spring的默认范围不是原型,会话或请求:每次请求进入时我们都不需要创建新服务.但是为什么要使用singleton?当服务是无状态的时,它是线程安全的,并且它可以扩展到任意数量的并发请求,因此不需要同一服务的第二个副本.

与EJB不同,有状态和无状态的bean,Spring只有一种类型的bean:无状态.如果你想管理国家,你必须自己做.就像之前的回答已经指出的那样,无状态是迄今为止更好的选择,因为它更快,更可扩展,更易于维护,它也是REST架构所倡导的.有状态的豆子在纸面上可能看起来很棒,多年来它已被证明是一场灾难.

  • 在多线程程序中,单例不一定会崩溃,决定因素是有状态与无状态。任何没有实例变量的类总是线程安全的。只有线程安全单例作为实例变量的单例(参见@Autowired 和@Inject)也是线程安全的,你可以编写一个程序来测试它。 (2认同)
  • 我猜想当您说“单独的线程访问同一个bean”时,您是在谈论在单个bean中访问相同的实例变量吗?与方法中的局部变量不同,实例变量位于堆中,并且在方法调用后不会获取垃圾。获得对这些变量的访问可能会引起争议,并降低程序的生命力。通过仅将线程安全的单例和ThreadLocals作为实例变量,您基本上避免了争用(也称为锁),并且强制要求必须在其他地方(例如客户端,分布式缓存或数据库)维护状态。 (2认同)

Jak*_*ski 9

无状态bean规则:)如果你不打算在bean中保存状态数据,那么每个bean只有一个实例就足够了.你还应该记住,这不是JVM单身人士 - 只是春天的单身人士.因此,您不必仅提供私有构造函数和任何getInstance()方法.

引用Spring文档:

当bean是单例时,将只管理bean的一个共享实例,并且对具有与该bean定义匹配的id或id的bean的所有请求将导致返回一个特定的bean实例.

只有在必须保留一些会话详细信息时,才应使用例如会话范围.