简体   繁体   English

什么时候使用 Spring 原型作用域?

[英]When to use Spring prototype scope?

I want to know when should I exactly use the prototype scope in Spring?我想知道我什么时候应该在 Spring 中使用prototype作用域? I have understood that singleton returns the same object instance if the bean is requested for.我已经理解,如果请求 bean, singleton返回相同的对象实例。

Then why should we consider prototype ?那我们为什么要考虑prototype呢?

Explanations with examples would help a lot to understand the need for it.带有示例的解释将非常有助于理解对它的需求。

To be clear simple definitions:明确简单的定义:

  • Prototype scope = A new object is created each time it is injected/looked up.原型范围 = 每次注入/查找时都会创建一个新对象。 It will use new SomeBean() each time.每次都会使用 new SomeBean()

  • Singleton scope = The same object is returned each time it is injected/looked up.单例范围 = 每次注入/查找时都返回相同的对象。 Here it will instantiate one instance of SomeBean and then return it each time.这里它将实例化SomeBean一个实例,然后每次都返回它。

Prototype bean is created at the time of usage. Prototype bean 是在使用时创建的。 So when you would like to have stateful beans there is a strong need sometimes to have prototypes scope or when you don't want to cache any values in beans.因此,当您想要有状态的 bean 时,有时强烈需要原型作用域,或者当您不想在 bean 中缓存任何值时。 Prototype bean can be associated with one session or some call.原型 bean 可以与一个会话或某个调用相关联。

Example:例子:

A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state;数据访问对象 (DAO) 通常不配置为原型,因为典型的 DAO 不保存任何会话状态; it was just easier for this author to reuse the core of the singleton diagram.这位作者更容易重用单例图的核心。

There are some interesting use cases by using scope prototype you will build a better and reliable application design/architecture, for example, a real-time system.有一些有趣的用例通过使用范围原型,您将构建更好和可靠的应用程序设计/架构,例如,实时系统。

Imagine that you must build a real-time system for vehicle tracking, and you will have 2.000.000 cars sharing information every 5 seconds, In the server side, you will work with two or more distinct group of configurations, one for Cars and another one for Trucks.想象一下,您必须构建一个实时车辆跟踪系统,每 5 秒将有 2.000.000 辆汽车共享信息,在服务器端,您将使用两个或多个不同的配置组,一个用于汽车,另一个用于一种用于卡车。

Based on this simple example, if you design your application to work with distinct configuration groups in memory through the prototype pattern you will achieve a better performance.基于这个简单的示例,如果您将应用程序设计为通过原型模式在内存中使用不同的配置组,您将获得更好的性能。

So, in this case, whenever the server receives a new message from a Truck, for example, the server will get the instance of the configuration in memory from a hashmap of instances of VehicleGrupConfiguration and then apply the configuration behavior that this message must have, eg: like time-out, retry... and etc.因此,在这种情况下,例如,每当服务器收到来自卡车的新消息时,服务器都会从VehicleGrupConfiguration实例的哈希映射中获取内存中的配置实例,然后应用此消息必须具有的配置行为,例如:像超时,重试...等。

I would like to highlight that there are many ways to implement this situation, but this example shows that a prototype pattern is very powerful in matters of performance and design patterns.我想强调的是,有很多方法可以实现这种情况,但是这个例子表明原型模式在性能和设计模式方面非常强大。

As the documentation says, creating a bean Foo with prototype scope is same as calling:正如文档所说,创建一个具有原型范围的 bean Foo 与调用相同:

Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);

The only good reason to use a prototype scope bean instead of new that is when the dependencies used for creation and initialization of the instance should be kept outside the code that needs a new instance.使用原型作用域 bean 而不是new的唯一理由是,用于创建和初始化实例的依赖项应该保留在需要新实例的代码之外。

An example is if you wanted to write persistence code similar to EJB2 Java Entity beans, such as例如,如果您想编写类似于 EJB2 Java Entity bean 的持久性代码,例如

Person p = ...
p.setName("John Doe");
p.save(); // write to DB

Instead of using the JPA way而不是使用 JPA 方式

Person p = new Person();
p.setName("John Doe");
personService.save(p); // write to DB

In the entity bean code style, the person instance needs to know how it should be persisted, so it needs to be injected with persistence details that the code writing a person should not be aware about.在实体 bean 代码风格中,person 实例需要知道它应该如何持久化,因此需要注入持久化细节,而这些细节是编写 person 的代码不应该知道的。

Another example: If you want to use the non-threadsafe SimpleDateFormat Java class in many places of your application, with a format pattern from a configuration file(maybe using different formats depending on other conditions).另一个示例:如果您想在应用程序的许多地方使用非线程安全的 SimpleDateFormat Java 类,请使用配置文件中的格式模式(可能根据其他条件使用不同的格式)。 Instead of creating a new format instance in all those places loading also the formatting string from a file (or spring property), you could use the prototype scope to get a fresh instance every time, with the details of setting the common format being in one place.不是在所有这些地方创建一个新的格式实例,还从文件(或 spring 属性)加载格式字符串,您可以使用原型范围每次都获取一个新实例,设置通用格式的细节在一个地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM