Saturday, May 14, 2022

Spring Bean Scopes

 Spring Singleton Scope : Singleton in Spring guarantees to create only one bean instance for given bean per id definition per container.  that means if we define same bean with two id or name than two instance world be created.

Spring singleton pattern is different from gang of four singleton pattern. While gang of four Singleton pattern ensures that one and only one instance is created per ClassLoader.

Example : Bean define only once but calling two times. So its return same instance of  same bean.

package com.example.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

import com.example.app.model.User;

@SpringBootApplication
public class SpringBootApp {
	public static void main(String[] args) {
		ApplicationContext appContaxt = SpringApplication.run(SpringBootApp.class, args);

		User objUser1 = appContaxt.getBean("user", User.class);
		System.out.println("HadhCode for objUser1 : " + objUser1.hashCode());

		User objUser2 = appContaxt.getBean("user", User.class);
		System.out.println("HashCode for objUser2 : " + objUser2.hashCode());
	}

	@Bean(name = "user")
	public User user() {
		return new User();
	}
}

Output : 

HadhCode for objUser1 : 1413858762
HashCode for objUser2 : 1413858762

As you can see in the above example we have define user bean only once and it is bydefault singleton. and we call bean 2 times but its return same bean as it returns same hashCode.

Example : same bean(Singletone bean) with two different id or name.

package com.example.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

import com.example.app.model.User;

@SpringBootApplication
public class SpringBootApp {
	public static void main(String[] args) {
		ApplicationContext appContaxt = SpringApplication.run(SpringBootApp.class, args);

		User objUser1 = appContaxt.getBean("user", User.class);
		System.out.println("HadhCode for objUser1 : " + objUser1.hashCode());

		User objUser2 = appContaxt.getBean("user1", User.class);
		System.out.println("HashCode for objUser2 : " + objUser2.hashCode());
	}

	@Bean(name = "user")
	public User user() {
		return new User();
	}
	
	@Bean(name = "user1")
	public User user1() {
		return new User();
	}
}

Output : 

HadhCode for objUser1 : 1739989024
HashCode for objUser2 : 2063549093

As you see in the output of above program if we define same been (singletone been) with two different id or name then two instance of bean would be created. As it returns different hashCode.

Example Prototype scope :

package com.example.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

import com.example.app.model.User;

@SpringBootApplication
public class SpringBootApp {
	public static void main(String[] args) {
		ApplicationContext appContaxt = SpringApplication.run(SpringBootApp.class, args);

		User objUser1 = appContaxt.getBean("user", User.class);
		System.out.println("Prototype been : HadhCode for objUser1 : " + objUser1.hashCode());

		User objUser2 = appContaxt.getBean("user", User.class);
		System.out.println("Prototype been : HashCode for objUser2 : " + objUser2.hashCode());
	}

	@Bean(name = "user")
	@Scope("prototype")
	public User user() {
		return new User();
	}
}

Output of prototype bean scope : 

Prototype been : HadhCode for objUser1 : 1573752639
Prototype been : HashCode for objUser2 : 1245794392

As you can seen in the output of bean while scope of bean is prototype. we have define bean only once but while calling bean two time and its returns different hashCode that means its create new instance every time while we call prototype bean in spring.