Difference between Java Singleton and Spring Singleton?

There is common misunderstanding between Spring Singleton and Java Singleton classes.  If you don’t know Singleton design pattern Please read Singleton Design pattern first.

Java singleton class is per Classloader and Spring’s singleton is per application context.

Java considers something a singleton if it cannot create more than one instance of that class within a given class loader, whereas Spring would consider something a singleton if it cannot create more than one instance of a class within a given container/context.

 

Singleton

Let’s understand very important concept about Spring Singleton by below given scenario –

Let suppose We have two bean definition in Bean configuration file and in main class we are trying to perform below test –

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

ApplicationContext ctx = new ClassPathXmlApplicationContext( "configFiles/User.xml");

User user1 = (User) ctx.getBean("beanA");

User user2 = (User) ctx.getBean("beanB");

System.out.println(user1 == user2);

System.out.println(user1 + "::" + user2); } }

In Spring Configuration file – User.xml

 <bean id="beanA" class="com.example.User" scope="singleton"> 
        <property name="name" value="Vivek Panday"/> 
 </bean>
<bean id="beanB" class="com.example.User" scope="singleton">  <property name="name" value="Upsilonwin@Vivek"/>  </bean>

Here, I create two beans of the Scope class and make Spring Scope a singleton, now checking the references.

Usually, There can be 3 consideration regarding above code as given below :

  • This code will not compile. It will throw an error at runtime, as you can not define two Sspring beans of the same class with Singleton Scope in XML. (Very rare)
  • The reference check will return true, as the container maintains one object. Both bean definitions will return the same object, so the memory location would be the same. (Often)
  • The reference check will return false, which means Spring Singletons don’t work like they said earlier. (A few)

The last option is correct consideration regarding above scenario, A Spring Singleton does not work like a Java Singleton.

Let see output of the above code –

Reference Check ::false
User [name=Vivek Panday]::User [name=Upsilonwin@Vivek]

According to the Spring documentation:

“When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.

To put it another way, when you define a bean definition and it is scoped as a singleton, then the Spring IoC 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 named bean will result in the cached object being returned.”

So it is clear that for a given id, a Spring container maintains only one shared instance in a singleton cache.

In my example, I use two different ids (userA and userB), so the Spring container creates two instances of the same class and binds them with respective ids, then stores them in a Singleton cache.

You can think of a Spring container as managing a key-value pair, where the key is the id or name of the bean and the value is the bean itself. So, for a given key, it maintains a Singleton. So if we use that key as a reference to or of other beans, the same bean will be injected to those other beans.

In summation, Spring guarantees exactly one shared bean instance for the given id per IoC container, unlike Java Singletons, where the Singleton hardcodes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader.

 

You may also like

Leave a Reply

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