2
votes

Hello guys I am trying to understand how exactly prototype Scope works in Spring IoC.

For prototype beans I tried to understand by:
1. Reading this again and again but could not understand fully(https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-other-injection)
2. Tried to debug via source code,only understood one thing if we do not specify proxyMode, it will not create proxy for prototype bean.
3. default ScopedProxyMode for prototype scope is DEFAULT which typically equals NO.. unless configured in component scan.

So I have 3 examples here:

Case A: Prototype bean used independently(not having any dependency or is not dependency for any bean) without proxymode defined

@Bean
@Scope("prototype")
public Employee employee(){
  return new Employee();
}

Case B: Prototype bean inside a singleton bean as dependency without proxymode defined

@Bean
@Scope("prototype")
public Employee employee(){
  return new Employee();
}

@Bean
@Scope("singleton")
public Department department(){
  return new Department();
}

Case C: Prototype bean inside a singleton bean as dependancy with proxymode defined

@Bean
@Scope("prototype",proxyMode= ScopedProxyMode.TARGET_CLASS)
public Employee employee(){
  return new Employee();
}

@Bean
@Scope("singleton")
public Department department(){
  return new Department();
}

Guys questions here are:

  1. How will case A, case B and case C work?
  2. I am trying to understand what exactly will be correct way.
  3. Also not specifying proxymode is correct or not?
  4. What happens when proxyMode is not set? how does prototype work then?

What I typically saw in implementation examples on internet is people often do not configure proxyMode either mistakenly or are not aware about this option or maybe they are right.

Thank you for your valuable time.

1

1 Answers

1
votes
  • A, B, and C will all return new instance of Employee when requested.
  • A and B are usual ways to use prototype scopes.
  • Not specifying is the usual way. Though in some instances where scope is RequestScope or Session scope, etc, it might make sense to specify proxyMode. Regarding specifying proxyMode, see the last paragraph.
  • If not set, you get the expected behavior. That is, you get new instance every time a bean instance is requested.

The prototype scope instructs Spring to instantiate a new instance of the bean everytime a bean instance is requested by the application.

You should consider using prototype scope in the following scenarios:

  • If you have a bean that has a lot of writable state, you may find that the cost of synchronization is greater than the cost of creating a new instance to handle each request from a dependent object.
  • Some dependent objects need a bean that has private state so that they can conduct their processing separately from other objects that depend on the bean. In this case, singletons are clearly not suitable. Consider prototypes.

It is a good practice that your beans should implement some interface. In that case, Spring uses JDK proxy mechanism to create proxy of your class. But implementing interface is not a requirement. If no interface is implemented by your bean, then Spring uses CGLIB library to create proxy of your bean (unless a class is annotated with @Configuration in which case a different proxy mechanism is used).

By specifying proxyMode=ScopedProxyMode.TARGET_CLASS, you are forcing Spring to use CGLIB proxy mechanism. In the end, just providing @Scope("prototype") is sufficient.

On a side note, know that if you have any methods that hook into lifecycle of a bean (like @PreDestroy, implementing DisposableBean interface, or destroyMethod as a flag in @Bean), then those methods will never be called in prototype scoped beans.