Monday, May 21, 2007

Hello World Spring

For those programmers that only think a spring is something that can contract and expand, you're missing out on a particularly useful and more and more essential, programming framework.

It is the first time in my 6 year programming life cycle that I have used spring on a project and I must say, there is no going back. Its benefits are incalculable. Regardless of the size of the application the Spring Application framework adds enormous value.


What exactly is Spring then, or more accurately, what is the Spring Framework?



Spring is a framework which enables the efficient development and maintenance of high quality applications. It is an infrastructure which handles many of the every day which developers would otherwise have to do. It has many facets, with the various components both tightly integrated and complementary. But the biggest win with “spring-core” at it is affectionately known is that gives the application “Inversion of Control” or otherwise known as Dependency Injection.


Let's do this by example...

Consider the following piece of code...

public class BusinessObject() {

WindowsMailService mailService = new WindowsMailService();

public void sendMail(String recipientAddress, String message) {

validateRecipientAddress(recipientAddress);

try {

mailService.dispatchMail(recipientAddress, message);

catch (Exception e) {

LOG.error(“send failed”, e);

}

}

}


In the above example, if you have read Robert Martin's brilliant “Agile Software Development” you'd already be pointing out that you're violating the Dependency Inversion principle, and that is that dependencies should go “down” and not “up”. In this case if I wished to use a different mechanism to send the mail, maybe a LinuxMailService or even change the mode of transport it would cause a change to this class. i.e. The “higher” class would require a change if a changed the “lower class”. So in other words, changing details, i.e. Nuts and bolts of the mail send mechanism would cause a change in the higher level business logic of the application. This is something we want to avoid. By the way, it's also violating the open-closed principle.

It would be a lot better to abstract the message dispatch mechanism via an interface and then remove the dependency between the business logic and the message dispatch mechanism.

You may now be asking, so where does spring fit in. Well, even if we abstracted via an interface, we would still need to get at the service to send the mail somehow. This is where spring comes in. If I were to use spring to construct the above infrastructure I would first add a property to our business object above which takes a IMesssageDispatchService interface and then create a file which defined the infrastructure.

This file of xml is provided to a spring definition loader which would load the file in and create a context. The context would create the beans defined in the file, business.logic and service.mail and make then available via a getBean(String) method. It would instantiate them as the class specified and with any properties specified. In the above example it would call the “setMessageService” method on the BusinessObject with an instance of the MailService class. Thus the creation of the infrastructure has now been abstracted out into this file. Plugging in another message dispatch service would mean coding the service and then changing the xml definition file. No change to the calling context or any of its code, necessary.

So to show you...

IBusinessObject business = (IBusinessObject)context.getBean(“business.logic”);

You've probably already noticed tha changing the mechanism used to send the mail is as simple as changing the definition file. As long as the service.mail bean implements the ImessageDispatchService interface it can point to any class.


So then to give you a whirlwind summary of the advantages from my own experience, here goes.

  • Abstraction of the details

    Spring lends itself to a system where the high level components do not have dependency on the low level components

  • Management of Dependencies

    When you create a spring managed bean you can easily specify the dependencies (i.e. Other beans) which that bean depends on. Spring will then go and build those various dependencies for you and you end up with a fully built up bean. Those beans should also be managed by spring. You don't have to code the plumbing.

  • Simplifying and Enabling a good design

    One of the problems I've often found when designing an application is working out the relationships between the objects and keeping those relationships clean. I've often found myself simply making a singleton out of my service objects and thereby making them available wherever they are required. I've often felt uneasy about this because I allow any object to have access to any other object and the relationships are not explicit. i.e. Because it is a singleton it can be referenced anywhere without limitations. Using spring allows those relationships to be controlled and explicitly defined (in an xml file) but at the same time it provides a mechanism to provide easy access to the services. The spring developers do not recommend that you do to much of the context.getBean calls illustrated above. This should only be done for the “root” of your infrastructure.

  • Flexibility

    Spring uses an xml file to define the infrastructure. For this reason changing the infrastructure is as simple as changing an xml file, and spring provides quite a few efficiencies in how you can change this xml file, via a property file for example. In our project for instance, we can change from container managed transactions to hibernate managed transactions as simply as changing a value in a properties file.


I think the key issue with spring is that it is a framework. It is a framework for building an application. It's analogous to a building. Spring is the framework while the application is the bricks. Because you already have a framework, adding aop for instance, is simple, the framework enables it. It does a lot of the “heavy lifting” of management and infrastructure, leaving the developer free to work on the interesting bits.


An Example of spring in action...

In our project we have junit test which test at the service level and these tests test locally (outside the container and not via web services). Now because the service level is what is presented to the outside world, this is the level which is exposed by web services, and there is thus a one to one mapping between the service level and the wsdl's. Now for this reason I felt it was possible to switch those junit tests to test against a running remote application server, and I achieved this switch by adding a bit of spring infrastructure definitions and I only had to change one line in the test code!

Spring has become as essential in my day to day life as a programmer as an IDE. I would not consider not using it in any application, no matter what the size.

When I came on the project I had never used it, but then I had not been involved in developing an enterprise application and now I cannot be without it.