我想知道我应该在Spring什么时候使用prototype
范围?我已经理解,如果请求bean,singleton
将返回相同的对象实例。
那我们为什么要考虑prototype
?
通过示例进行说明有助于理解对它的需求。
答案 0 :(得分:15)
明确简单定义:
原型范围=每次注入/查找时都会创建一个新对象。它每次都会使用新的SomeBean()
。
Singleton scope =每次注入/查找时返回相同的对象。这里它将实例化SomeBean
的一个实例,然后每次都返回它。
原型bean在使用时创建。所以,当你想拥有有状态的bean时,有时需要有原型范围,或者当你不想在bean中缓存任何值时。原型bean可以与一个会话或一些调用相关联。
示例:
数据访问对象(DAO)通常不配置为原型,因为典型的DAO不会保持任何会话状态;这个作者更容易重用单例图的核心。
答案 1 :(得分:6)
使用范围原型有一些有趣的用例,您将构建更好,更可靠的应用程序设计/体系结构,例如,实时系统。
想象一下,你必须建立一个实时的车辆跟踪系统,每隔5秒就会有2.000.000辆汽车共享信息, 在服务器端,您将使用两组或更多组不同的配置,一组用于汽车,另一组用于卡车。
基于这个简单的示例,如果您通过原型模式设计应用程序以在内存中使用不同的配置组,那么您将获得更好的性能。
因此,在这种情况下,每当服务器从Truck收到新消息时,服务器将从 VehicleGrupConfiguration 实例的散列图中获取内存中的配置实例,然后应用此消息必须具有的配置行为,例如:如time-out,retry ...等等。
我想强调有很多方法可以实现这种情况,但是这个例子表明原型模式在性能和设计模式方面非常强大。
答案 2 :(得分:0)
如文档所述,使用原型范围创建bean Foo与调用相同:
Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);
使用原型范围bean而不是new
的唯一很好的理由是,用于实例创建和初始化的依赖项应保留在需要新实例的代码之外。
一个示例是,如果您想编写类似于EJB2 Java Entity bean的持久性代码,例如
Person p = ...
p.setName("John Doe");
p.save(); // write to DB
代替使用JPA方式
Person p = new Person();
p.setName("John Doe");
personService.save(p); // write to DB
在实体bean代码样式中,person实例需要知道应如何持久化,因此需要向其注入持久性详细信息,而编写人员的代码不应该知道这些持久性细节。
另一个例子: 如果要在应用程序的许多地方使用非线程安全的SimpleDateFormat Java类,请使用配置文件中的格式模式(根据其他条件,可以使用不同的格式)。您可以使用原型作用域每次获取一个新的实例,而无需在所有这些位置创建新的格式实例,也可以从文件(或spring属性)中加载格式字符串,详细信息将通用格式设置在一个实例中。地方。
答案 3 :(得分:0)
阅读Spring Documentation On Bean Scope后,您将了解有关bean作用域的想法
有关实际示例,请参阅此堆栈溢出问题Real World use case of bean scopes。