Sunday, November 05, 2006

Legacy Bean wrapping strategies with Spring

So far, my experiences with Spring were with new web applications, so it was easy enough to get up and running with Spring using Thomas Risberg's Spring MVC, Step by Step tutorial. However, what I wanted to do now was to introduce Spring into an already existing web application built using a home grown framework based on the JSP-as-Handler pattern described in page 337 of Martin Fowler's Patterns of Enterprise Application Architecture book.

The idea is to continue with the existing framework for features which are already live, and use the Spring MVC Framework and its IoC style configuration for new features in the web application. New features should be able to re-use, as far as possible, the business logic which have been codified in the Java classes in the old framework. We could have taken the path of least resistance and just adapted to building new features with the existing framework, but we chose Spring because it is easier, more powerful and more intuitive to use, and is thus likely to enhance productivity.

This article will detail some strategies I used to wrap or reference existing (or "legacy") beans in the Spring applicationContext configuration file. The list here is quite short, and reflect only the things I had to do so far. If you can think of other ideas or situations, please post them in the comments or point me to links, and I will include them.

Configure only what you need

I was dreading the exercise of having to figure out and configure whole stacks of beans before I started this, but then I realized that our new Spring controllers need to only declare references to service beans that it needs, i.e. to the next level in the abstraction layer. Since the existing framework did not depend on any sort of property injection, the service beans know how to populate and instantiate themselves with DAO and other lower level beans without any help from a bean factory. The lower level beans typically use the Locator pattern to locate configuration information from a registry.

It may be worth moving these to Spring later and dispensing with the registry altogether in favor of the Spring application context, but that can be done in stages.

Static Singletons

By default, Spring builds beans and sets the declared dependencies at application startup. Unless told otherwise (with the singleton="false" attribute), what you get is a reference to a singleton. If the singleton bean has a no-args constructor, then it can be configured in the context as a bean. If the singleton bean has an explicit constructor, you can use constructor injection to build a reference to the bean, and then pass the bean into your new Spring beans as a property.

It is tempting to just make a static call to the bean from within your Spring beans, but then you are not using IoC anymore.

Beans with static initializers

These can generally be used as is, since the first time it is called (by the Spring BeanFactory), the static block would be called. However, it may be worth moving the static block out into an init() method in the bean, and letting Spring call the init() method on application startup after the bean has been fully populated with the configured setter properties using the init-method="init()" attribute in the bean definition.

Beans configured via constructors

There are usually two approaches to IoC, one constructor based and the other setter based. There are valid arguments on both sides, but it is possible to declare beans using both constructor based and setter based injection in Spring. So if a bean needs to be built using a non-default constructor, then this can be done from within Spring.

Resources

Spring is very well-documented, and Chapter 3 of the Spring Framework documents was very helpful when trying to come up with the appropriate wrapping strategy.

Be the first to comment. Comments are moderated to prevent spam.