Saturday, July 21, 2007

Introducing Spring

The first time AOP expert Nicholas Lesiecki explained AOP to me, I didn't understand a word he was saying; and I felt much the same the first time I considered the possibility of using IOC containers. The conceptual basis of each technology alone is a lot to digest, and the myriad of new acronyms applied to each one doesn't help -- particularly given that many of them are variations on stuff we already use.

Like many technologies, these two are much easier to understand in practice than in theory. Having done my own research on AOP and IOC container implementations (namely, XWork, PicoContainer, and Spring), I've found that these technologies help me gain functionality without adding code-based dependencies on multiple frameworks. They'll both be a part of my development projects going forward.

In a nutshell, AOP allows developers to create non-behavioral concerns, called crosscutting concerns, and insert them in their application code. With AOP, common services like logging, persistence, transactions, and the like can be factored into aspects and applied to domain objects without complicating the object model of the domain objects. 

Developing with a new framework without unit testing is like walking on a new trapeze wire without a net: sure you could do it, but you're going to bleed. I prefer to develop with a net, and for me that net is TDD. Before DbUnit came along, testing code that was dependent on a database could be a little tough. DbUnit is an extension of JUnit that provides a framework for unit tests dependent on a database. I used DbUnit to write the test code for the example classes in this article. While not present in the article, the DbUnit code is part of the article source code (see Resources). Or for an introduction to DbUnit, see "Control your test-environment with DbUnit and Anthill" (developerWorks, April 2004) by Philippe Girolami.

IOC allows me to create an application context where I can construct objects, and then pass to those objects their collaborating objects. As the word inversion implies, IOC is like JNDI turned inside out. Instead of using a tangle of abstract factories, service locators, singletons, and straight construction, each object is constructed with its collaborating objects. Thus, the container manages the collaborators.

Spring is both an AOP framework and an IOC container. I believe it was Grady Booch who said the great thing about objects is that they can be replaced; and the great thing about Spring is that it helps you replace them. With Spring, you simply inject dependencies (collaborating objects) using JavaBeans properties and configuration files. Then it's easy enough to switch out collaborating objects with a similar interface when you need to.

Spring provides an excellent on-ramp to both IOC containers and AOP. As such, you don't need to be familiar with AOP in order to follow the examples in this article. All you need to know is that you'll be using AOP to declaratively add transactional support to your example application, much the same way that you would use EJB technology. See Resource to learn more about Spring.