Blog

Configuration-hell remedy with Singleton injection

18 Oct, 2006
Xebia Background Header Wave

One of the most heard complaints about Spring projects is the seemingly unavoidable configuration-hell that silently creeps in every bigger project after some time.
Singleton injection is a simple practice that can significantly reduce configuration and corresponding injection code. Besides that, it provides possibilities you might not have been aware of enabling you to get most out of Spring. In this blog you will learn which advantages Singleton injection provides. It illustrates how to implement it and specifies clear guidelines in which circumstances it is applied best.
Where applicable, Singleton injection can be an elegant solution that provides significant code and configuration simplification.

At the beginning of a Spring project, when the applicationContext.xml(s) resemble a fallow field, it is easy to keep the overview of your beans. As time goes by most of us have been facing the configuration-hell growing out of proportion, making it difficult to find your way in the bean jungle. There are several commonly applied best-practices to postpone this problem as long as possible, such as the usage of abstract declarations, splitting up the bean configuration in several subconfigurations or Eclipse’s Spring IDE.
Besides that I have come across another way, which can significantly contribute to reduce spring configuration, eliminate superfluous code and provide other interesting advantages you might not have been aware of before. The way to achieve that is called Singleton injection.

The familiar way

Consider the following piece of code and configuration:
[java]
public class AnyService {
private Logger log = Logger.getLogger(AnyService.class);
private MessageResource messageResouce;
public setMessageResource(MessageResource messageResouce) {
this.messageResouce = messageResouce;
}
public void execute() {
if(condition)
log.error(messageResource.getMessage(“error.msg.key.1”));
// more code
}
}
public class AnyDAO {
private Logger log = Logger.getLogger(AnyDAO.class);
private MessageResource messageResouce;
public setMessageResource(MessageResource messageResouce) {
this.messageResouce = messageResouce;
}
public List findAll() {
if(condition)
log.warn(messageResource.getMessage(“error.msg.key.2”));
//more code
}
}
[/java]
[xml]

property name=”resourceLocation” value=”classpath:/bundle.properties”/>


[/xml]
Apparently, the MessageResource class is used throughout the application, actually by each class that needs to log something. Since we want to initialize the MessageResource class with the proper configuration with the BeanFactory facilities, we configure the MessageResource class as a spring bean and inject it in every class that makes use of it. The latter is followed by tedious instance variable/setter code and injection configuration. This should sound familiar to you.

The alternative: Singleton injection

Fortunately, there is an easier way. Consider the following piece of code:
[java]
public class AnyService {
private Logger log = Logger.getLogger(AnyService.class);
public void execute() {
if(condition)
Log.error(MessageResourceSingleton.getInstance().getMessage(“error.msg.key.1”));
// more code
}
}
[/java]
As you can see, most of the spring-related injection hassle seems to have disappeared. At least, that might be the first impression. Instead of cumbersomely injecting the MessageResource bean in all classes that use it, we take a slightly different approach:
1. We write a wrapper class applying the Singleton pattern (here MessageResourceSingleton) that wraps an implementation of the MessageResource class
2. Then add configuration that injects the implementation (MessageResource) into the Singleton wrapper (MessageResourceSingleton)
The following code and configuration illustrates the Singleton injection approach:
[java]
public class MessageResourceSingleton implements MessageResource{
/** MessageResource implementation to be injected */
private MessageResource messageResource;
/** singleton instance */
private static MessageResourceSingleton singleton = new MessageResourceSingleton();
/**
* Gets singleton
* @return singleton
*/
public static MessageResourceSingleton getInstance(){
return singleton;
}
/**
* Setter for the MessageResource implementation used to inject
* the implementation
* @param messageResource
*/
public void setMessageResource(MessageResource messageResource) {
this.messageResource = messageResource;
}
/**
* Delegates the call to the injected implementation
* @param args arguments
* @return message
*/
public String getMessage(String key) {
return messageResource.getMessage(key);
}
}
[/java]
[xml]

[/xml]
Any class that wants to use the MessageResource implementation simply calls:
[java]
MessageResourceSingleton.getInstance().getMessage(“any.key”);
[/java]
By doing so, we can use all the configuration power spring provides when defining the implementation bean. The code, which uses the implementation, is not only freed of superfluous injection code and corresponding configuration but is – as the IoC principle demands –totally unaware that Spring is pulling the strings (or beans ;-)).

Your gains with Singleton injection

So, when using Singleton injection these are your gains:
• Reduced configuration and less code (inject once use everywhere)
• Injected Singletons can be used in classes that are not part of the beanwiring chain
• Static methods can use injected Singletons
• Injected Singletons can serve as beanwiring starting points
• Increased productivity (instant usage of injected code)
Since it all seems so simple, practical and advantageous, why not use Singleton injection everywhere in you code?

When to use Singleton injection

The tradeoff when considering Singleton injection is simplicity versus flexibility. The constraint is that the Singleton can only wrap one specific implementation. Therefore, every class that makes use of the Singleton wrapper will have to stick with this particular implementation. You still can have several implementations available (for unittesting, mocking etc.) but at runtime only one of these can be used throughout the application.
In other words, when you face a “one size fits all” scenario you have a case for a Singleton injection. In more detail, the following preconditions have to be present in order to make Singleton injection a useful choice:
• A spring bean is used in various, peripheral parts of the application
• A spring bean has the characteristics of an utility class that needs to be initialized with external resources or other parameters
• A spring bean has to be accessible by classes that are not part of the beanwiring chain
• It is sufficient that at runtime only one specific implementation of the spring bean is used throughout the application

Real world cases for Singleton injection

I have used Singleton injection on various projects. The following type of classes have proven to be an excellent candidate for Singleton injection:
• MessageResource utility like the one used in this example
• Logger utility that needs to perform logging to a database or queue
• IDGenerator that gets id’s used for logging or messaging from a database
• CodeMapper that maps technical codes to a description
• Business Delegate, which can be used as startingpoint of the beanwiring
• Any utility you want to use in a framework or component, which does not provide hooks to inject spring beans (in case they are still out there…)

Conclusion

Where applicable Singleton injection can be an elegant solution that provides significant code and configuration simplification. Additionally, it enables you to profit from “Spring injection power” outside the standard beanwiring chain. All this can be achieved with such a simple thing like Singleton injection. It enables you to do more with less – isn’t this what programming is all about?

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts