1

I am have a test class and I have defined it in my spring bean config file as below:

   <bean id = "springsingleton1" class = "com.learn.stackoverflow.general.SpringSingleton"/>
   <bean id = "springsingleton2" class = "com.learn.stackoverflow.general.SpringSingleton" scope="prototype"/>
   <bean id = "springsingleton3" class = "com.learn.stackoverflow.general.SpringSingleton"/>

My expectation was that this will throw some exception because firstly I have defined a singleton bean and then I am trying to create another prototype of the same, or if exception is not thrown then I will always get the same instance for all 3 cases but I am getting different instance. Below is code:

    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\E_Drive\\Projects\\Workspace\\Test\\CS101\\src\\com\\learn\\stackoverflow\\general\\bean.xml");
    SpringSingleton springSingleton11 = (SpringSingleton) applicationContext.getBean("springsingleton1");
    SpringSingleton springSingleton21 = (SpringSingleton) applicationContext.getBean("springsingleton2");
    SpringSingleton springSingleton22 = (SpringSingleton) applicationContext.getBean("springsingleton2");
    SpringSingleton springSingleton3 = (SpringSingleton) applicationContext.getBean("springsingleton3");
    SpringSingleton springSingleton12 = (SpringSingleton) applicationContext.getBean("springsingleton1");

    System.out.println("springSingleton11 : " + springSingleton11.hashCode());
    System.out.println("springSingleton21 : " + springSingleton21.hashCode());
    System.out.println("springSingleton22 : " + springSingleton22.hashCode());
    System.out.println("springSingleton3 : " + springSingleton3.hashCode());
    System.out.println("springSingleton12 : " + springSingleton12.hashCode());

Output:

springSingleton11 : 1658926803
springSingleton21 : 210652080
springSingleton22 : 1652149987
springSingleton3 : 1107730949
springSingleton12 : 1658926803

How I am getting more than one instance, doesn't Spring enforces singleton?

Please note that I have read this question and it doesn't answer my doubts.

pjj
  • 2,015
  • 1
  • 17
  • 42

3 Answers3

4

From Spring documentation:

Spring’s concept of a singleton bean differs from the Singleton pattern as defined in the Gang of Four (GoF) patterns book. The GoF Singleton hard-codes the scope of an object such that one and only one instance of a particular class is created per ClassLoader. The scope of the Spring singleton is best described as per container and per bean. This means that if you define one bean for a particular class in a single Spring container, then the Spring container creates one and only one instance of the class defined by that bean definition. The singleton scope is the default scope in Spring.

So, Spring's doesn't ensure that there is only one instance of such a class, it only ensures that when you call a singleton bean (for example, as per your example repeatedly getting springsingleton1) then you get the same instance.


A work around is that instead of defining the bean in your bean config file, annotate your class as @Scope("singleton") and then always use the autowiring to get the instance of this class, but you have to strictly ensure that you are not defining this bean in your bean config file because if you do that (same as what you did in your question) then even though you have @Scope("singleton") annotation still you can have multiple instances.

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70
1

Spring does not enforce the Singleton design pattern, the scope=singleton merely means that whenever you reference the bean (e.g. by it's id), you'll get the same instance from the Spring container.

An example:

<bean id="a" class="MyClass1" scope="prototype">
    <property name="b" ref="b" />
</bean>
<bean id="b" class="MyClass2" scope="singleton" />

In such config, you'll get a new instance of MyClass1 whenever you reference bean a or whenever you request the bean from the container, but each of these instances will point to the same single instance of MyClass2 in their b property.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
0

You have two singleton beans, springsingleton1 and springsingleton3. They share the same class, but the beans themselves are singletons. You will always receive the same object when asking for either of them, but the objects themselves are not the same.

A singleton bean is not the same thing as a singleton class.

Prototype works just like you'd expect.

Kayaman
  • 72,141
  • 5
  • 83
  • 121