我想知道什么时候应该确切地使用Spring中的原型
范围?我已经理解单例
如果请求bean,则返回相同的对象实例。
那我们为什么要考虑原型
?
用例子进行解释将有助于理解它的必要性。
明确简单的定义:
>
原型范围=每次注入/查找时都会创建一个新对象。它每次都将使用new有Bean()
。
Singleton scope=每次注入/查找时都会返回相同的对象。这里它将实例化一个有Bean
的实例,然后每次都返回它。
原型bean是在使用时创建的。因此,当您想要有状态bean时,有时非常需要有原型范围,或者当您不想在bean中缓存任何值时。原型bean可以与一个会话或一些调用相关联。
示例:
数据访问对象(DAO)通常不配置为原型,因为典型的DAO不持有任何会话状态;作者更容易重用单例图的核心。
通过使用范围原型,您将构建更好且可靠的应用程序设计/架构,例如实时系统,有一些有趣的用例。
想象一下,你必须建立一个车辆跟踪的实时系统,你将有2.000.000辆汽车共享信息每5秒,在服务器端,你将使用两个或更多不同的配置组,一个用于汽车,另一个用于卡车。
基于这个简单的示例,如果您将应用程序设计为通过原型模式使用内存中的不同配置组,您将获得更好的性能。
因此,在这种情况下,每当服务器收到来自Truck的新消息时,例如,服务器将从车辆GrupConfiguration实例的hashmap中获取内存中的配置实例,然后应用此消息必须具有的配置行为,例如:超时、重试等。
我想强调,有很多方法可以实现这种情况,但是这个例子表明原型模式在性能和设计模式方面非常强大。
正如留档所说,创建具有原型范围的bean Foo与调用相同:
Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);
使用原型范围bean而不是new
的唯一好理由是,用于创建和初始化实例的依赖项应该保留在需要新实例的代码之外。
举个例子:
// need to explicitly mention dependencies here
public void createdWithNew(Dependency dependency1, Dependency dependency2) {
Foo foo = new Foo(dependency1, dependency2, ...);
foo.doSomething();
}
// Dependencies managed in class Foo by Spring
public void createdWithSpring(Foo foo) {
foo.doSomething();
}
例如,如果您想编写类似于EJB2Java实体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代码风格中,人实例需要知道应该如何持久化,因此需要注入编写人的代码不应该知道的持久化细节。
另一个例子:如果你想在应用程序的许多地方使用非线程安全的SimpleDateFormatJava类,并从配置文件中使用格式模式(可能根据其他条件使用不同的格式)。你可以使用原型范围每次都获得一个新的实例,而不是在所有这些地方创建一个新的格式实例,同时从文件(或Spring属性)加载格式化字符串。设置通用格式的细节在一个地方。