Thursday, 7 July 2011

Spring Bean Scopes: Singleton and Prototype

Spring defines two bean scopes in an application’s context: singleton and prototype. A singleton scoped bean is one that obeys the rules of the Singleton Pattern: ie. there is only ever one instance of your bean and this is the default when Spring creates its beans. On the other hand, when a bean is marked as a prototype, then for every call to getBean(...) Spring will create a new instance especially for you.

This can be demonstrated using the following code. In this scenario I’ve created a RandomNumberBean class that generates a random number when it’s instantiated saves the number in an instance variable.

public class RandomNumberBean {

private static Random rand;

private final int value;

public RandomNumberBean() {

rand = new Random();
// Generate a number up to 50
value = rand.nextInt(50);

public String toString() {

StringBuilder sb = new StringBuilder("\nRandomNumberBean value: " + value);
return sb.toString();

I’ve then created a simple XML config file with two entries for my RandomNumberBean class: one with ‘singleton’ scope and one with ‘prototype’ scope.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""

 <bean id="MySingleton" class="example_1_bean_type.RandomNumberBean" scope="singleton"/>
 'singleton' scope is the default scope. The line above is equivalent to writing: 
 <bean id="MySingleton" class="example_1_bean_type.RandomNumberBean" />
 <bean id="MyPrototype" class="example_1_bean_type.RandomNumberBean" scope="prototype"/>

I’ve then got some client code that calls getBean(...) to get hold of each of the RandomNumberBean beans four times and print out its value.

    ApplicationContext ctx = new FileSystemXmlApplicationContext(
Constants.PATH_TO_RESOURCES + "BeanType.xml");

for (int i = 0; i < 4; i++) {
RandomNumberBean instance = ctx.getBean("MySingleton", RandomNumberBean.class);
("Singleton " + i + " Value: " + instance.toString());

for (int i = 0; i < 4; i++) {
RandomNumberBean instance = ctx.getBean("MyPrototype", RandomNumberBean.class);
("Prototype " + i + " Value: " + instance.toString());

From the results, you can see that the singleton prints out the same value each time (22) and the prototype prints of a sequence of different values:

Singleton 0 Value: 
RandomNumberBean value: 22
Singleton 1 Value: 
RandomNumberBean value: 22
Singleton 2 Value: 
RandomNumberBean value: 22
Singleton 3 Value: 
RandomNumberBean value: 22
Prototype 0 Value: 
RandomNumberBean value: 16
Prototype 1 Value: 
RandomNumberBean value: 24
Prototype 2 Value: 
RandomNumberBean value: 32
Prototype 3 Value: 
RandomNumberBean value: 49

Obviously, when using singletons, you have to be aware of the usual threading issues as different threads will access the same instance variables. There are a couple of simple strategies you can use to avoid these kinds of problems including:
  • Don’t use instance variables.
  • Make your bean immutable by declaring your instance variables final and using constructor args.
  • Use ThreadLocal to create a set of instant variables for every thread.

No comments: