54

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.

VedantK
  • 9,728
  • 7
  • 66
  • 71
Rahul
  • 619
  • 1
  • 5
  • 15

4 Answers4

17

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.

VedantK
  • 9,728
  • 7
  • 66
  • 71
RMachnik
  • 3,598
  • 1
  • 34
  • 51
  • 16
    So which type of beans should be created as prototype? – GD_Java Dec 25 '17 at 14:14
  • 4
    Only those that you want to have fresh instance every time. Honestly, I would not use prototype in 99% of cases. – RMachnik Dec 26 '17 at 12:05
  • 5
    A good practice is to pass dependencies through the constructor. Therefore, you should never use scope prototype. Instead, you should use new or a singleton factory. – Réda Housni Alaoui Aug 21 '18 at 09:01
  • Still its not clear on, when to use prototype ? May b a real time example would help here – Saurabh Oza Nov 29 '18 at 02:53
  • 1
    Basically, imagine situation that you want to have every time new object when you access bean Prototype bean. Your bean is going to be instantiated every time you want to access it like you use `new User()` in simple POJO. – RMachnik Nov 29 '18 at 10:43
  • 50
    How does this answer have upvotes? It doesn't specify when to use prototype scope at all. It just diverts away from the question by saying why DAO is not typically configured as a prototype which doesn't answer the question one bit. – theprogrammer Aug 15 '19 at 16:25
  • 1
    It does it. I gave basic facts about prototype vs singleton scope and example where not to use it. Pretty old thing but still valid. – RMachnik Aug 19 '19 at 11:04
  • 3
    The portion after "Example" is copied and pasted without attribution from [Section 3.5.2 The prototype scope](https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch03s05.html#beans-factory-scopes-prototype) of Spring documentation. It also omits the image which was actually the example. – Joshua Taylor Sep 26 '19 at 16:43
8

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.

Lucas Pires
  • 1,281
  • 14
  • 21
  • 15
    To improve performance of a real-time system, the code should be designed to minimize the frequency of object instantiation during transactions. Prototypes are intended to be instantiated each time they are requested from the Spring framework. This behavior of prototypes can degrade real-time performance. The commentator is correct that, to improve performance, configuration data should be accessed from memory, but be careful using prototypes to implement that design requirement. Instead, consider defining a group of Singletons of the same type, each created at startup with different state. – Mark Norman Sep 09 '18 at 17:59
  • Hi @MarkNorman could you please share an example how can I came up with this solution "Instead, consider defining a group of Singletons of the same type, each created at startup with a different state" Sounds very interesting your idea, Thank you very much for sharing your feedback. – Lucas Pires Sep 10 '18 at 16:04
  • 2
    You will find an example here: https://www.baeldung.com/spring-data-jpa-multiple-databases. Take note that there are two configuration beans of type `LocalContainerEntityManagerFactoryBean`, one named `userEntityManager` and another named `productEntityManager`. – Mark Norman Sep 10 '18 at 18:20
5

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.

tkruse
  • 10,222
  • 7
  • 53
  • 80
  • hi @tkruse I would like to understand what do you mean when you write "when the dependencies used for creation and initialization of the instance should be kept outside the code that needs a new instance". I have a similar example where I use a new instead of a bean because I need a new instance of the class every time it is called and it has to hold state for each session. My use case is very similar to this one https://stackoverflow.com/questions/69026436/spring-controller-business-logic and I am unsure of the use of prototypes. – Ana Sustic Sep 06 '21 at 09:52
  • 1
    I tried giving more examples, does that help? – tkruse Sep 06 '21 at 10:02
2

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.

Abhijeet Gite
  • 79
  • 1
  • 6