A Spring Singleton is not a Singleton

September 14, 2006 – 22:03 | java, spring

OK, I know this sounds like another one of those "a white horse is not a horse" arguments, but from my observation on the Spring forums and other blog reading, some clear distinction between the semantics of a Spring singleton and a classical Java singleton has become much necessary. The overloaded term has caused quite some confusion, especially for someone who has just started picking up Spring.

First let's examine how a bean is made a singleton in Spring:

XML:
  1. <bean id="foo" class="Foo" singleton="true">
  2. </bean>

What the 'singleton' attribute really makes Spring do is to cache and always return the same bean instance for all the requests on this bean. As far as the comparison to a classical Java singleton is concerned, there are two distinctions that need to be noted here:

1. The caching of a bean instance happens only within a single Spring ApplicationContext instance - referred to as the "Spring IoC container" in Spring documentation. So obviously if I have another bean defined with the same id and the same class in a separate ApplicationContext instance, that one would be a completely different one. (Note that here we are talking about ApplicationContext instances, not context definition XML files, because more than one file can be loaded into one context instance. As far as the singleton scope is concerned, it is the instance not the files that counts.) In contrast, if we look at a Java singleton, its scope of singularity applies to the "universe" managed by the classloader that loaded this class.

2. When a bean reference is requested from an application context, the id or the name is used to identify the bean wanted. On the other hand, when we call Bar.getInstance(), we are really using the class Bar to identify what we instend to receive. If that didn't sound like something significant, consider a scenario where two beans of the same class are defined in the same ApplicationContext:

XML:
  1. <bean id="foo1" class="Foo" singleton="true">
  2. </bean>
  3. <bean id="foo2" class="Foo" singleton="true">
  4. </bean>

There will be two bean instances created in this context, both of type Foo, but one under id 'foo1', another under id 'foo2'. Clearly that's behavior we'd never see in Java singletons.

Having noted the two distinctions above, it becomes clear that a Spring singleton has some semantics rather orthogonal to those of a Java singleton - "orthogonal" in the sense that neither is the singularity of a Spring singleton meaningful in any scope definition based on classloaders, nor is a Spring singleton instance associated to any specific class. On the other hand, as we all would recognize, those are the two fundamental characteristics of a Java singleton.

Hopefully, this confusion will be clarified to some extent in Spring 2.0, with the newly introduced 'scope' attribute and the session, request, and global session scopes. Also Section 3.4 Bean Scope in the Spring 2.0 Reference explicitly puts out a warning note on the difference between the Spring singleton scope and the classical Singleton Pattern. Although I still think that it could have had the issue completely addressed, had the scope value "singleton" been renamed to something like "container" altogether - but then, I can also see some new confusion arising from that, like "how is this supposed to map to the singleton thing from before?"

Trackback from your site, or follow the comments in RSS.
  1. 10 Responses to “A Spring Singleton is not a Singleton”

  2. good article about this confusion!
    and there is a section in the RD J Chapter 4,'Avoid a Proliferation of Singletons by Using an Application Registry', seem to also talk about this issue.

    By freizl on Sep 22, 2006

  3. very well explained! thanx

    By pwu on Sep 12, 2007

  4. Good explanation, thnk!

    By Raish on Apr 4, 2008

  5. Thanks a lot for this article and removing my confusion.

    By Parag Soman on Aug 28, 2008

  6. Very Nicely Explained !

    By Pawan on Apr 16, 2009

  7. In this context, it's also useful to note that by default Spring beans are singleton - i.e even if you don't specify singleton="true" or scope="singleton", it's created as a Spring-Singleton. So, there are certain cases where we need to explicitly say scope="prototype" to avoid multithreaded issues.

    By jaa on Jun 9, 2009

  8. I it very nice explanation. So you are gonna say Spring developers have to take a special consideration in this regard.

    By shan on Jun 22, 2009

  9. Nice Explanation!!!

    By Thamayanthi on Jun 25, 2009

  10. Perfectly nice One!!!

    By JEx on Oct 30, 2009

  11. Very well explained. Always wondered about the fine differences between the two. Thanks for the explanation!

    By Amal on Jan 10, 2010

Post a Comment