Spring instantiation strategies

In relation to my previous post I’d like to shortly discuss the different instantiation methods Spring supports. We’ve reviewed the concept of a FactoryBean in detail, but there’s way more you should know about how Spring creates instances of types wired up in your context.

Prototypes and singletons

The most important characteristic for a bean definition in a Spring context is whether or not the bean is a singleton. Tweaking the singleton attribute is the way to specify this characteristic:

<bean class="example.MyObject" singleton="false"/>

versus

<bean class="example.MyObject" singleton="true"/>

You have to keep one thing in mind about Spring singletons:

Beans defined as singletons in a Spring ApplicationContext, are singletons only in the scope of the ApplicationContext you’ve defined the bean in.

In other words, if I have two distinct application contexts both having defined a singleton bean, each context will contain exactly one instance of the singleton. This is different from the way we implemented singletons in Java usually, using a static getInstance() method along with a private constructor to prevent instantiation. Here, there will be one instance of the bean per VM or better, per distinct ClassLoader sibling the singleton class was loaded in.

Als note that by default a bean in a context is a singleton, so you don’t have to specify singleton="true" with every bean.

It’s good practice to develop your code in a thread-safe way. There’s no reason to resort to changing your beans to prototypes or even use things like instance pooling unless you’ve really need it!

Ways Spring instantiates your objects

And now for the real meat: how does Spring actually instantiate your objects. Spring is designed for use with all objects of all types your can think of. Using one of the following instantiation methods, you should be able to wire almost any Spring bean in your context, whether it are legacy objects that need special treatment or plain and simple JavaBeans with a no-args constructor. As far aas I know there’s only one type of object you can’t instantiate. I’ll talk about that a bit near the end of this post.

In the example listed below, we’ll be using the Spring ApplicationContext.getBean() call to show the behavior of the different methods we have. Usually, you don’t have to resort to using the ApplicationContext API, but for demonstration purposes it works pretty well here. Remember that under the covers obtaining beans, dependency injecting beans into other beans all boils down to Spring using the getBean() method on the ApplicationContext. In other words, the following would result in two distinct calls to ApplicationContext.getBean("testBean"). Because we didn’t specify the singleton attribute, Spring will make this bean a singleton (remember, this is the default behavior) and although there are two calls to getBean() for this specific bean identifier, there will be only one instance of the bean.

<bean id="testBean" class="example.TestBean"/>
 
<bean id="anotherBean" 
    class="example.AnotherBean">
  <property name="collaborator" ref="testBean"/>
</bean>
 
<bean id="yetAnotherBean" 
    class="example.YetAnotherBean">
  <property name="collaborator" ref="testBean"/>
</bean>

Let’s review (a really simplified almost pseudo-code version of) what Spring does behind the scenes as well:

ApplicationContext ctx = new ApplicationContext();
TestBean mySingleton = new TestBean();
ctx.addBean(mySingleton);
 
AnotherBean ab = new AnotherBean();
TestBean collForAb = ctx.getBean("testBean");
// retrieve test bean for use as collaborator
ab.setCollaborator(collaboratorForAb);
 
YetAnotherBean yab = new YetAnotherBean();
// same reference as collForAb since it's a singleton
TestBean collForYab = ctx.getBean("testBean");
yab.setColllaborator(collaboratorForYab);

If we would have set the singleton attribute to false we would have gotten two different instances of the TestBean class!

Note that the above is a really simplified version of what Spring does behind the scenes. It is just to show how Spring works and let you understand how to work with all the different instantiation methods. If you try to compile this code, it won’t even work.

Using a no-args constructor

In my my previous post we already shortly discussed setter injection and using a no-args constructor. The most well-known way Spring instantiates your objects is using a JavaBean-style no-args constructor. Consider the following:

public class NoArgsConstr {
  public NoArgsConstr() {
  }
}
<bean id="noArgs" class="example.NoArgsConstr"/>

The above example roughly translates to the following:

NoArgsConstr myBean = new NoArgsConstr();
ctx.addBean(myBean);

As we’ve seen before, the noArgs bean is defined as a singleton (since this is the default behavior) and therefore every call to ApplicationContext.getBean("myBean") (hence every reference you create to the bean in your context) will result in the exact same instance to be returned or referenced.

Other than no-args constructor

You can also use constructors that do take arguments. The following illustrates how this works:

class OtherConstr {
  public OtherConstr(int a, String b) {
    // do something with a and b
  }
}
<bean id="otherConstr" class="example.OtherConstr">
  <constructor -arg index="0" value="1"/>
  <constructor -arg index="1" value="alef"/>
</bean>

And as you would expect this will result in a bean being added to the context created by issuing the new OtherConstr(1, "alef") statement. Note that Spring automatically detects the types of your constructor arguments and property values (unless you specifically specify the type attribute).

Using a static factory method

In yesterday’s post we’ve seen that using FactoryBeans you can instantiate all kinds of objects that might not have a public constructor. One of those might be types with a static factory method. There’s a shortcut to obtaining instances of beans with static factory methods. Using the factory-method method attribute in combination with the class attribute, Spring will create the bean using the method and class you’ve specified. Consider the following class:

class MyClass {
 
  MyClass() { }
 
  public void applyRandom(Random r) {
    // do something with random
  }
 
}

The following factory creates an instance of MyClass:

class MyClassFactory {
 
  private MyClassFactory() {}
 
  public static MyClass createMyClass(
      long seed) {
    MyClass myClass = new MyClass();
    Random r = new Random(seed);
    myClass.applyRandom(r);
    return myClass;
  }
}

If you want to use the MyClass bean in combination with the factory, you’d have to use the following in your Spring context:

<bean id="myFactory" 
  class="example.MyClassFactory
  factory-method="getInstance">
  <constructor -arg value="12345"/>
</bean>

Note that using the constructor-arg elements will cause the values to be passed to the factory method you’ve specified whereas any nested property elements will be applied to the object the factory method returns.

Using a factory method from a different bean

Where the factory-method in combination with a class attribute would cause Spring to call a static factory method on the class specified, in combination with the factory-bean attribute the factory method will have to be defined on another bean defined in your context. This allows you to configure the factory as well using Spring DI. Consider the following rewritten example (the same MyClass object is used here, the factory differs a bit):

class MyClassFactory {
 
  public MyClassFactory(long seed) {
    this.random = new Random(seed);
  }
 
  public MyClass createMyClass() {
    MyClass myClass = new MyClass();
    myClass.applyRandom(random);
    return myClass;
  }
}

The following XML fragment would cause Spring to first instantiate the MyClassFactory and register it as a bean in the context. The second thing it would do is call the createMyClass() on that same bean and register the result in the context as well:

<bean id="myFactory" class="example.MyClassFactory">
  <constructor -arg value="12345"/>
</bean>
 
<bean id="myClass"
  factory-bean="myFactory"
  factory-method="createMyClass"/>

Note that with this option, you can specify arguments to pass to the factory method as well. Just as above, you’d have to use the constructor-arg elements along with the myClass bean.

FactoryBeans

Another way to instantiate your beans is using the FactoryBean interface. I won’t be discussing this here in more detail.

Things to consider when using different instantiation strategies

Although all the instantiation strategies are nicely supported, you shouldn’t use them when creating new classes. Be sure not to design your classes using a factory method of some sort if you don’t know why you’re actually doing it. The instantiation strategies are part of Spring because we’d like you to wire up any object of any type including objects not created by yourself.

Another thing yo keep in mind when using factory methods for example is the singleton aspect of Spring beans. The following for example, would not cause multiple SingletonBeans to be available in the context, since the factory method we’re using in fact returns a singleton itself. So setting the singleton attribute to false here in fact doesn’t work!

class SingletonBean {
  private SingletonBean instance = new SingletonBean();
  public static getInstance() {
    return instance;
  }
}
<bean id="mySingleton"
  class="example.SingletonBean"
  factory-method="getInstance"
  singleton="false"/>

Protected constructors

Spring has the option to instantiate beans with a protected constructor. Using the setAccessible(true) method on a constructor, Spring is still able to instantiate your beans. Don’t design your classes with a protected constructor! Again, this option is meant to solve situations where you don’t have control over the class you want to wire up.

The one bean you can’t wire up in Spring

As far as I know there are very little situations where you can’t use one of the above instantiation strategies to wire a bean into a Spring context. The only situation I can think of right now is (apart from a class with a private constructor and no getInstance() method–but those classes can’t be instantiated anyway):

  • A class with a package friendly constructor
  • in a package which is sealed
  • with a security policy which doesn’t allow setAccessible(true)

6 Responses to “Spring instantiation strategies”


  1. 1 ac May 20th, 2006 at 5:21 am

    “a couple of dutch rants” in english means: “Two Dutch Rants”

    There is no other meaning of this title.

  2. 2 Raoul Duke May 19th, 2007 at 2:04 am

    Thanks for the lucid post. It greatly helps me understand Spring. Question: is there a way to have Spring configure a class that has no instances? E.g. that is only made of static fields and methods? I’d like Spring to set a value on a static field.

    thanks.

  3. 3 Secondt Jun 26th, 2008 at 3:33 pm

    Hello,
    sorry for any bothering by this posting regarding topic, duplicate threads and whatsoever.

    I need a complete explanation about bean instantiation in application server after reading blog entries at “arendsen”. To ease the discussion, I’ve prepared the following scenario:

    Env: WLS9.2, Spring1.2.8, Java5
    Note: using of ejb is a Must

    I have a stateless ejb, which extends AbstractStatelessSessionBean. Inside this bean “ContextSingletonBeanFactoryLocator” is correctly used in method “setSessionContext”. Then a bean “theService” is retrieved inside the method “onEjbCreate”. It is assumed that “theService” bean is very lightweight and its implementation is not thread safe. So I set the “singleton” to false, namely prototype. Further the implementation of “theService” has access to other beans which are also not thread safe and these beans are also marked as prototype.

    Question: Can these prototype beans garbage collected? If yes, how? If not, is there any rescue solutions?

    There is a “CommonsPoolTargetSource”, which utilizes under scene java weak references. But that is perhaps only feasible for heavyweight objects, right?

    Best Regards

  4. 4 Dinesh Nov 13th, 2008 at 12:58 am

    Hi,
    I read your article it is nice. I however want to know how can I use Spring to get objects from a cache. I am trying to use Webspehere Object cache to store objects for caching and i want the cached objects returned when I need them. I do not know how to wire then, one way I can think of is using factory but that seems to be not so good method. I will aprreciate if you can help me.

  1. 1 A Couple of Dutch Rants » Blog Archive » Spring instance management part I - pooling Pingback on Jul 6th, 2005 at 6:34 pm
  2. 2 ringtone Trackback on Oct 5th, 2005 at 11:31 am

Leave a Reply