Saturday, 12 November 2011

JavaEE revisits the Design Patterns: Singleton

If you haven't read Design Patterns: Elements of Reusable Object-Oriented Software by the famous Gang of Four or Head First Design Patterns , I strongly suggest you to start with either of them since I will rather show how to implementing the patterns than to describe what they are. However, if you are already familiar with the concept, JavaEE might offer you a pathway to many abilities some considered to be unnatural.

To start coding you would need:
 - JavaEE6 SDK
 - a JavaEE server
 - an IDE (Eclipse/Netbeans/IntelliJ)

JavaEE SDK for your operating system can be downloaded from Oracle's website. Some of the SDK bundles also include Glassfish. If you prefer to use another JavaEE server you may go for JBoss or TomEE which is the regular Tomcat bundled with OpenJPA and OpenEJB. Also you may choose to download Netbeans which comes bundled with the SDK and the Glassfish in just one package (great for beginners, no configuration needed).

Singleton Pattern can be useful although it is out fashion. The idea is basically having only one instance of a class which might be expensive to create. The usual way is just making the constructor private and either creating the object or returning the already cached instance by controlling if it has been created before. There are some pitfalls which the pattern may fail on race conditions or via reflection if the implementation is not right.

JavaEE offers a simple elegant way to create and use Singletons just by adding a simple annotation. Create a new project to start, basically a JavaEE Web Profile Project would be enough to run the examples.

package com.devchronicles.singleton;


import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
/**
 *
 * @author Murat Yener
 */


@Singleton
public class SomeExpensiveBean {
    @PostConstruct
    public void start(){
        System.out.println("Started!");
    }
}

Thanks to annotations, JavaEE6 do not need any configuration xml. You may see there is a beans.xml in the project which is actually empty and you do not need to add any configuration here. @Singleton annotation marks the class as an Singleton EJB and the container takes care of handling the only instance. To make sure the instance is created at startup, the @Startup annotation is used.

...
@Startup
@Singleton
public class SomeExpensiveBean {
 ...

However the Singleton bean might rely on some other bean which we may need to make sure it was created before "SomeExpensiveBean". Surprisingly annotations would still be enough to configure.

...
@Startup
@DependsOn("SomeConfigurationBean")
@Singleton
public class SomeExpensiveBean {
 ...

... and a new bean which the container would make sure it is created first.

package com.devchronicles.singleton;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
/**
 *
 * @author Murat Yener
 */

@Startup
@Singleton
public class SomeConfigurationBean {
    @PostConstruct
    public void start(){
        System.out.println("Well, I started first!!!");
    }
}

Thats it! The beans will be created as single instances and any time you inject the bean you will get the same instance.