ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Archive for May, 2008

The Singleton Story

Posted by ice09 on May 26, 2008

As you may know, Spring is much about Singletons. By default, Spring beans are Singletons, ie. if you inject bean A in bean B, both of it are usually created once and reused all over your application.

Update (08.07.2008):
Inspired by Preston Lee’s comment, I wondered why the failures of Singletons (which I mostly agree with) in general do not affect my daily work.
I realized I am not really talking about Singletons in this post.
There is a brief and very good explanation of this topic here.
In short: this post is not about (VM-wide) Singletons in the usual sense, but about Spring’s default Bean-ID to (unique instance) bean mapping. Spring Beans are referenced by IDs and Spring by default returns the same, unique instance of a bean for each ID. This post discusses alternatives to Springs default unique instance handling. However, remember that these beans are no Singletons in the original meaning.

Consider the simplest example:


    <bean id="single" class="my.Single">
        <property name="prototype" ref="prototype" />
    </bean>

    <bean id="prototype" class="my.Prototype"></bean>

With this configuration, the following test app

package my;

public class Prototype {

    static int counter;

    Prototype() {
        System.out.println("Prototype constructor called.");
        counter++;
    }

    public String toString() {
        return String.valueOf(counter);
    }

}

the class which uses the Singleton:

package my;

public class Single {

    protected Prototype prototype;

    public void show() {
        System.out.println("prototype id: " + prototype);
    }

    public void setPrototype(Prototype prototype) {
        this.prototype = prototype;
    }

}

the main test class:

package my;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
        Single single = (Single) app.getBean("single");
        single.show();
        single.show();
        single.show();
        single.show();
    }

}

obviously prints out

Prototype constructor called.
prototype id: 1
prototype id: 1
prototype id: 1
prototype id: 1

Now, despite the apparently never occurring need of non-singleton beans, what can you do if you just want to have one, just for fun?

I, unbelievably, really faced the situation where I needed a non-singleton.

It was like this: you write some datatransfer stuff. It can happen that you need to parse Xml to get it done. You want to do this using a nice Singleton-Tool like this…


void transfer() {

  Document doc = this.xmlutils.createDocument();

  doSomethingWithDoc(doc);

}

…with xmlutils being nicely injected by Spring? Nice? No. Really ugly. Whatever sophisticated Xml-stuff you use, it almost certainly will be non-threadsafe.

So, yes, you really need some non-Singleton.

Searching for this will give you some pseudo-solutions like this.

Ok, I hate it. Definitely not what I want to have.
So, look at this one:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <bean id="prototype" class="my.Prototype" scope="prototype">
        <aop:scoped-proxy/>
    </bean>

    <bean id="single" class="my.Single">
        <property name="prototype" ref="prototype" />
    </bean>

</beans>

Now, that’s Springish, isn’t it? We proxy the object we inject and let Spring control the usage of our prototype bean, the scope of which we set with the attribute “scope” on the bean itself.

This prints out almost what we want:

Prototype constructor called.
Prototype constructor called.
prototype id: 2
Prototype constructor called.
prototype id: 3
Prototype constructor called.
prototype id: 4
Prototype constructor called.
prototype id: 5

Yes, a hundred bucks for the wise guy who can tell me how to omit the first (senseless) object instance – I just can’t figure it out. But since a prototype should per definition be lightweight, it just does not matter (to me) if there is one useless instance generated the first time.

So for me, that’s the best anti-singleton pattern.

Advertisements

Posted in Singletons | Tagged: , , , | 4 Comments »