When to use Spring prototype scope?

53.4k Views Asked by At

I want to know when should I exactly use the prototype scope in Spring? I have understood that singleton returns the same object instance if the bean is requested for.

Then why should we consider prototype?

Explanations with examples would help a lot to understand the need for it.

4

There are 4 best solutions below

8
On BEST ANSWER

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.

  • 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.

Prototype bean is created at the time of usage. 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. Prototype bean can be associated with one session or some call.

Example:

A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state; it was just easier for this author to reuse the core of the singleton diagram.

3
On

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.

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, e.g: like time-out, retry... and etc.

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.

2
On

As the documentation says, creating a bean Foo with prototype scope is same as calling:

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.

As an example:

// 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();
}

An example is if you wanted to write persistence code similar to EJB2 Java Entity beans, such as

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

Instead of using the JPA way

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.

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). 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.

0
On

Prototype scoped beans are useful for services that have longer running or resource-intensive operations and do not need to maintain state across multiple method calls. Creating a new instance of the bean for each method call ensures that resources are not shared across multiple requests and that each request is handled independently of others. This can help avoid potential concurrency issues and improve performance.

On the other hand, singleton scoped beans are useful for services that have short and quick operations or for services that need to maintain state across multiple method calls. By using a single instance of the bean, the state can be maintained across method calls and the overhead of creating a new instance for each method call can be avoided.

In general, it's important to choose the appropriate bean scope based on the specific needs of the service. If a service requires shared state across multiple method calls or needs to be lightweight and efficient, singleton scope is usually the better choice. However, if a service is long-running or resource-intensive, or needs to be isolated across multiple requests, prototype scope is usually the better choice.

Example:

Let's say you have an application that generates reports based on user inputs. Each report requires different sets of data and takes a long time to generate. You want to avoid generating the report multiple times if the user wants to see the same report again.

In this case, you can use a prototype-scoped bean to generate each report. When the user requests a report, you create a new instance of the report generator, generate the report, and return the report to the user. This way, if the user requests the same report again, a new instance of the report generator will be created, ensuring that the report is generated fresh and not reused.

If we use a prototype bean scope for a PDFGenerator bean, a new instance of the bean will be created every time a request is made to generate a PDF file. This is useful because PDF generation can be a resource-intensive operation that takes time, and we don't want to tie up our resources by generating multiple PDF files at the same time using the same instance of the bean. Each request for a PDF file will be handled by a separate instance of the PDFGenerator bean, so the resources won't be shared across multiple requests.

If we were to use a singleton bean scope for the PDFGenerator bean, there would only be one instance of the bean created at application startup. This means that if multiple users were trying to generate PDF files at the same time, they would be using the same instance of the PDFGenerator bean to do so. This could potentially lead to resource contention, as multiple users are competing for the same resource. Additionally, if one user's PDF generation process takes a long time to complete, it could cause other users' requests to be delayed.

In this scenario, using a prototype bean scope is the better choice, as it ensures that each request for a PDF file is handled independently of others and that resources are not shared across multiple requests. By creating a new instance of the PDFGenerator bean for each request, we avoid potential concurrency issues and improve performance.