Spring Boot

Complex Scenario of Spring Bean Scopes

In this article, we will discuss the complex scenario of Spring bean scopes. As we know the default bean scope of the bean is a singleton. Whenever we call getbean every time we will get the same bean instance from the application context. When application initialized JVM read all the configuration from the XML file or from the config class and loaded beans in the application context with a default bean scope singleton.

Spring Bean Scopes

To understand what happened in the background we need to enable the debug mode by adding below code in the application.properties file.

logging.level.org.springframework=debug

Show that we can identify what is happing in the background when we initialized the application.

Now in this article, we will discuss only prototype and singleton and its different way of use in the application.

Bean Scope
Singleton One instance per spring context
Prototype New bean whenever requested

Let’s create a java class to understand the above-mentioned scope.
RepoDaoLayer.java

@Component
public class RepoDaoLayer {

	 @Autowired
	 DatabaseConnection jdbcConnection;

	public DatabaseConnection getJdbcConnection() {
		return jdbcConnection;
	}

	public void setJdbcConnection(DatabaseConnection jdbcConnection) {
		this.jdbcConnection = jdbcConnection;
	}
}

As we can see in the above-mentioned code RepoDaoLayer has a dependency of DatabaseConnection bean. Whenever we initialized our application, spring will create an instance of DatabaseConnection along with an instance of RepoDaolayer.

Now let’s Create DatabaseConnection.java file

@Component
public class DatabaseConnection {

	
	 public DatabaseConnection() {
		 System.out.println("JDBC COONECITON");
	 }
}

Now Create DemoApplication.java main file to run the code.

@SpringBootApplication
public class DemoApplication {
static Logger LOG= LoggerFactory.getLogger(DemoApplication.class);
	public static void main(String[] args) {
			
ApplicationContextcxt=SpringApplication.run(DemoApplication.class, args);	
RepoDaoLayer dao= cxt.getBean(RepoDaoLayer.class);
	
LOG.info(dao.toString());
LOG.info(dao.getJdbcConnection().toString());
	
RepoDaoLayer da1= cxt.getBean(RepoDaoLayer.class);
LOG.info(da1.toString());
LOG.info(da1.getJdbcConnection().toString());
		
	}
}

As we can see we are getting two instances of RepoDaoLayer class using getBean. When we run the above code we will get below output:

Here we are getting the same instance of RepoDaolayer & DatabaseConnection every time because the default bean scope is the singleton.

Now What will happen when the parent class is prototype and child is a singleton?

Now I am making RepoDaoLayer.java class prototype. By using @scope(“prototype”) over RepoDaolayer.java class

@Component
@scope(“prototype”)
public class RepoDaoLayer {

...
}

Now run the main java file you will get below output:

As we can see in the screenshot we are getting the different instance of RepoDaolayer but same DatabaseConnection instance every time because of singleton nature of DatabaseConnection.

Now, what with happen if you make parent class as a singleton and child class as a prototype?

I am using @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) in DatabaseConnection.java class.

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DatabaseConnection {
...
}

Now run the main class. You will get the below output.


Now we can see we are getting same bean instances every time even we make DatabaseConnection class as a prototype? Why are we getting the same bean?

Because RepoDaoLayer class is singleton by nature and when we ask spring to give me bean of RepoDaolayer class it gives us a singleton bean without realizing that databaseConnection bean is the prototype.

If we really want to get different beans of DatabaseConnection whenever we request to Repodaolayer then we need to configure Proxy. The proxy will make sure that spring will give us new instances every time when we call RepoDaolayer bean. Below is the code to configure proxy bean of DatabaseConnecion.java class so that we can get new bean every time when we call Singleton bean.

@Component
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE,proxyMode=ScopedProxyMode.TARGET_CLASS)
public class DatabaseConnection {
...
}

Here we use something called proxyMode=ScopedProxyMode.TARGET_CLASS. Which make sure that each time we get new bean when we call RepoDaoLayer. Now we can get different bean of DatabaseConnection every time when you get an instance of RepoDaolayer.

Here we can see we are getting same instance of RepoDaolayer but different instance of DatabaseConnection class because of proxy. Instead of giving DatabaseConnection object spring give us the proxy object of DatabaseConnection.

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago