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);
}
@Override
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="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="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"/> </beans>
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);
System.out.println("Singleton " + i + " Value: " + instance.toString());
}
for (int i = 0; i < 4; i++) {
RandomNumberBean instance = ctx.getBean("MyPrototype", RandomNumberBean.class);
System.out.println("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:
Post a comment