Singleton Bean Vs. Pattern

1
2775

Difference Between Singleton Design Pattern and Spring Bean

This is a very popular interview question for Spring as well as design patterns. The answer to this question reveals the in-depth understanding of both the concepts. Does Spring’s singleton scope provides one and only one object of the class? If so, how does it handle all the requests? How it is different than Singleton Design pattern, if it is ?

The answer to this tricky question is actually simple and can only be understood if you know both the concepts completely. Reason being “Spring’s concept of a singleton bean is actually” far different from the Singleton Design pattern”.

Let’s see step by step how it is so different and what are the actual differences:

sun
One of it’s (class) type – Just like Sun

Singleton Design Pattern restricts the instantiation of a class to one object so that one and only one instance of a particular class will ever be created per Class Loader.

one of its type
So unique ‘per Class and per classloader’

I am not going to discuss Singleton design pattern much in detail here as it can be found easily anywhere. The focus would be more on Spring’s Singelton Scope and the difference between both the concepts.

One Per Container
Spring Singleton is ‘per Spring IOC Container and per bean’.

The container will create exactly one instance of the object defined by that bean definition. This single instance will be stored in a cache of such singleton beans and all subsequent requests and references for that bean return the cached object.

Now, we need to carefully understand that this object is single for the IoC Container and NOT the JVM or entire application.

The application itself can have multiple IoC containers as well and in that case the rule of getting same object breaks!!!
To understand the concept more clearly, we will create 2 different examples.

First one, to show how a single instance gets returned again and again by the container and what is the significance of having Singleton Scope in Spring Bean.

Second One, to show how different instances for the same bean are created even after having the scope Singleton at the time container gets re-instantiated. This example will show the multiple instances creation for the same bean but because of same IOC Container each would refer to the same one from the cache.

Sounds interesting? Lets get into the code now!!!

A Simple Bean Class Code:

package com.javatech;

public class SimpleBean {

 String theName;  
 
 public String getTheName() {
  return theName;
 }

 public void setTheName(String theName) {
  this.theName = theName;
 }
}


A simple 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  
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
   
    <bean id="simpleBean" class="com.javatech.SimpleBean" />  
 </beans>


Java Class instantiating the container and accessing the bean

package com.javatech;

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

public class SingletonExample {

 public static void main(String[] args) {
   ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "com/javatech/AppContext.xml" });  

   //Get the bean from context
         SimpleBean bean1 = (SimpleBean) context.getBean("simpleBean");  
         
         //Set the property of bean and print it
         bean1.setTheName("A Simple Bean of goyalsbit.com");  
         System.out.println("Bean name 1 : " + bean1.getTheName());
         
         // Get another instance but it actually returns the same bean  
         SimpleBean bean2 = (SimpleBean) context.getBean("simpleBean");  
         System.out.println("Bean name 2 : " + bean2.getTheName());  
 }
}
Run the Program and Console Output:
Bean name 1 : A Simple Bean of goyalsbit.com
Bean name 2 : A Simple Bean of goyalsbit.com

 

So that was the first example which showed us that no matter how many time you try to get the instance from container, you will get the same already instantiated and shared instance which is Singleton.
Now, let’s move to the second example to deep dive into it. Here we are going to have 2 instances of IoC container and then try to access the same bean. Lets see what happens then !!

Java Class instantiating the container twice and accessing the bean :

package com.javatech;

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

public class SingletonExample {

 public static void main(String[] args) {
   ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "com/javatech/AppContext.xml" });  

   //Get the bean from context
         SimpleBean bean1 = (SimpleBean) context.getBean("simpleBean");  
         
         //Set the property of bean and print it
         bean1.setTheName("A Simple Bean of goyalsbit.com");  
         System.out.println("Bean name 1 : " + bean1.getTheName());
         
         // Get another instance but it actually returns the same bean  
         SimpleBean bean2 = (SimpleBean) context.getBean("simpleBean");  
         System.out.println("Bean name 2 : " + bean2.getTheName());  
         

         // New application context again  
         ApplicationContext newContext= new ClassPathXmlApplicationContext(
         new String[] { "com/javatech/AppContext.xml" });
         // Get another instance but it actually returns the same bean  
         bean2 = (SimpleBean) newContext.getBean("simpleBean");  
         System.out.println("Bean name 2 This Time : " + bean2.getTheName());  

         // Compare the classloaders if they are same
         System.out.println("context classloader: "+context.getClassLoader());
         System.out.println("newContext classloader: "+newContext.getClassLoader()); 
 }
}

Console Output
Bean name 1 : A Simple Bean of goyalsbit.com
Bean name 2 : A Simple Bean of goyalsbit.com
Bean name 2 : null

context classloader: sun.misc.Launcher$AppClassLoader@a39137
newContext classloader: sun.misc.Launcher$AppClassLoader@a39137

So here if you see the classloader is same for both the ApplicationContext but the bean returned by both are different.

Hope the above code examples made the concept clear to you. Please share your thoughts and suggestions by writing back in comments.

Previous articleHow to find String Anagrams
Next articleJSP Introduction and Life Cycle
I have spent almost 10 years playing around Java and related technologies. I love to write on different topics and would be very much willing to hear back your feedback/suggestions on them. This site is a medium to share my knowledge with the Java folks and grow further. My other interests include traveling, driving, swimming and dance. But yes, my web site has become my passion over the time :) I live in Scotland and travel to India often, my roots being there.

1 COMMENT

LEAVE A REPLY