Categories
Spring Spring Core

Singleton vs Prototype Scope

In this Article we will look into the Difference Between Singleton and Prototype Scoped Beans in Spring with Example.

Bean Scopes means, to Define the Lifecycle and Visibility of a Bean in the Spring application context. 

Spring Framework Supports 6 different Scopes, among these Singleton and Prototype Scope can be used in Spring Core and all others can be used only when we use Web Aware ApplicationContext(REST API or Web MVC).

  1. Singleton(Default)
  2. Prototype
  3. Request
  4. Session
  5. Application
  6. Websocket 

We shall look at Singleton and Prototype Scopes in Detail here. I will write another one Article for all other scopes with Spring Web MVC in future.

Singleton Scoped Bean

Bean Definition Example : 

<bean id="employeeService" class="net.geekcoders.EmployeeServiceImpl" scope="singleton"></bean>

Below Diagram says How IoC Container will treat Singleton Scoped Bean.

  • If your Bean is Singleton Scoped the IoC Container will create exactly one Instance and Store it is a Cache for later use. 
  • For every request or reference to your Singleton bean the same Instance will be shared and no new instance will be created in a IoC Container. 

Example code

  • I’m creating EmployeeController, EmployeeManager, EmployeeServiceImpl classes with Singleton scopes. 
  • EmployeeService Object will be referenced by EmployeeController and EmployeeManager.
  • For Each call, the Container won’t create a new Bean Object, rather it will share an already created Instance from Cache.

For ease of use, I’m creating all the Classes and Interface in the same package.

EmployeeController Class : A Controller class with EmployeeService as Constructor Args.

package net.geekcoders;

public class EmployeeController {
	private EmployeeService employeeService;
	public EmployeeController(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
	public EmployeeService getEmployeeService() {
		return employeeService;
	}
	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
}

EmployeeManager Class : A Controller class with EmployeeService as Constructor args.

package net.geekcoders;

public class EmployeeManager {
	private EmployeeService employeeService;
	public EmployeeManager(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
	public EmployeeService getEmployeeService() {
		return employeeService;
	}
	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
}

EmployeeService Interface : Interface to define what EmployeeService type of Objects should have.

package net.geekcoders;

public interface EmployeeService {
	void addEmployee();
}

EmployeeServiceImpl : Implementation of EmployeeService with no-args constructor and Sysout to know how many times the Constructor has Invoked.

package net.geekcoders;

public class EmployeeServiceImpl implements EmployeeService{
	public EmployeeServiceImpl() {
		System.out.println("EmployeeService Instance Created");
	}

	@Override
	public void addEmployee() {
		System.out.println("Adding new Employee");
		
	}

}

EmployeeStarter : As this is a Spring-Core Application, we should have a main class with ApplicationContext Initialized to run the application. 

package net.geekcoders;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EmployeeStarter {

	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		EmployeeController controller = applicationContext.getBean("employeeController",EmployeeController.class);
		EmployeeManager manager = applicationContext.getBean("employeeManager",EmployeeManager.class);
	}

}

applicationContext.xml : Bean Definitions has been defined here with all the Beans as Singleton Scope

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="employeeController" class="net.geekcoders.EmployeeController" scope="singleton">
        	<constructor-arg ref="employeeService"></constructor-arg>
        </bean>
        
        <bean id="employeeManager" class="net.geekcoders.EmployeeManager" scope="singleton">
        	<constructor-arg ref="employeeService"></constructor-arg>
        </bean>
        
        <bean id="employeeService" class="net.geekcoders.EmployeeServiceImpl" scope="singleton"></bean>
</beans>

Now run the above application from EmployeeStarter class you can see the EmployeeServiceImpl called only one time for both the two references of EmployeeController and EmployeeManager Beans.

Key Terms

  • Singleton is a Default Scope in Spring
  • If no other scopes mentioned in Bean Definition, Container will treat your Bean as Singleton.
  • Exactly one Instance of a Bean will be created per IoC Container.
  • In our Example We demonstrated with EmployeeServiceImpl by multiple references from EmployeeManager and EmployeeController Beans.
  • For all the References exactly one Instance only created and Shared to EmployeeManager and EmployeeController Beans.
  • It can be used in a Stateful application.

Prototype Scoped Bean

Now we will look at the rarely used Prototype Scope by Slightly modifying the above example.

The above Diagram states How IoC will treat Prototype Scoped Bean.

We can see for every request or reference to the employeeService bean, the Container is creating new Instances and passed to the referrers.

Example Code

Slightly modify the applicationContext.xml file by replacing “singleton” to “prototype” in scope attribute and save the file.

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="employeeController" class="net.geekcoders.EmployeeController" scope="prototype">
        	<constructor-arg ref="employeeService"></constructor-arg>
        </bean>
        
        <bean id="employeeManager" class="net.geekcoders.EmployeeManager" scope="prototype">
        	<constructor-arg ref="employeeService"></constructor-arg>
        </bean>
        
        <bean id="employeeService" class="net.geekcoders.EmployeeServiceImpl" scope="prototype"></bean>
</beans>

Now run the application from the EmployeeStarter class you can see two times the EmployeeServiceImpl constructor is called.

Key Terms

  • Prototype Scoped Bean will create a new Instance every time the Bean is requested or referenced. 
  • It can be used in a Stateless application. 

Note :

  • We can provide reference of Singleton Scoped bean to another Singleton scoped bean and Prototype Scoped Bean to another Prototype Scoped Bean. 
  • If you mix it by referring to the Prototype Scoped Bean from Singleton Scoped bean, it will affect the Spring Bean Lifecycle. 
  • As Singleton will have only one instance throughout the IoC Container, Prototype bean won’t get a new instance every time. If you want to use Prototype Scoped Bean with Singleton Scoped Bean by creating a new instance every time without affecting the Prototype Bean Lifecycle, we have another one approach called Method Injection in Spring. We will look at this in a Separate Article.

That’s all for now on Bean Scopes in Spring – Core Article!!!

Happy Reading!!!

Leave a Reply

Your email address will not be published. Required fields are marked *