By Craig Walls and Ryan Breidenbach
Application context module

The core module's BeanFactory makes Spring a container, but the context module is what makes it a framework. This module extends the concept of BeanFactory, adding support for internationalization (I18N) messages, application life cycle events, and validation.

In addition, this module supplies many enterprise services such as e-mail, JNDI access, EJB integration, remoting, and scheduling. Also included is support for integration with templating frameworks such as Velocity and FreeMarker.

Spring's AOP module

Spring provides rich support for aspect-oriented programming in its AOP module. This module serves as the basis for developing your own aspects for your Spring-enabled application.

To ensure interoperability between Spring and other AOP frameworks, much of Spring's AOP support is based on the API defined by the AOP Alliance. The AOP Alliance is an open-source project whose goal is to promote adoption of AOP and interoperability among different AOP implementations by defining a common set of interfaces and components. You can find out more about the AOP Alliance by visiting their website at http://aopalliance.sourceforge.net.

The Spring AOP module also introduces metadata programming to Spring. Using Spring's metadata support, you are able to add annotations to your source code that instruct Spring on where and how to apply aspects.

JDBC abstraction and the DAO module

Working with JDBC often results in a lot of boilerplate code that gets a connection, creates a statement, processes a result set, and then closes the connection. Spring's JDBC and Data Access Objects (DAO) module abstracts away the boilerplate code so that you can keep your database code clean and simple, and prevents problems that result from a failure to close database resources. This module also builds a layer of meaningful exceptions on top of the error messages given by several database servers. No more trying to decipher cryptic and proprietary SQL error messages!

In addition, this module uses Spring's AOP module to provide transaction management services for objects in a Spring application.

Object/relational mapping integration module

For those who prefer using an object/relational mapping (ORM) tool over straight JDBC, Spring provides the ORM module. Spring doesn't attempt to implement its own ORM solution, but does provide hooks into several popular ORM frameworks, including Hibernate, JDO, and iBATIS SQL Maps. Spring's transaction management supports each of these ORM frameworks as well as JDBC.

Spring's web module

The web context module builds on the application context module, providing a context that is appropriate for web-based applications. In addition, this module contains support for several web-oriented tasks such as transparently handling multipart requests for file uploads and programmatic binding of request parameters to your business objects. It also cotains integration support with Jakarta Struts.

The Spring MVC framework

Spring comes with a full-featured Model/View/Controller (MVC) framework for building web applications. Although Spring can easily be integrated with other MVC frameworks, such as Struts, Spring's MVC framework uses IoC to provide for a clean separation of controller logic from business objects. It also allows you to declaratively bind request parameters to your business objects, What's more, Spring's MVC framework can take advantage of any of Spring's other services, such as I18N messaging and validation.

Now that you know what Spring is all about, let's jump right into writing Spring applications, starting with the simplest possible example that we could come up with.

1.3 Spring jump start

In the grand tradition of programming books, we'll start by showing you how Spring works with the proverbial "Hello World" example. Unlike the original Hello World program, however, our example will be modified a bit to demonstrate the basics of Spring.

Note: To find out how to download Spring and plug it into your project's build routine, refer to appendix A.

Spring-enabled applications are like any Java application. They are made up of several classes, each performing a specific purpose within the application. What makes Spring-enabled applications different, however, is how these classes are configured and introduced to each other. Typically, a Spring application has an XML file that describes how to configure the classes, known as the Spring configuration file.

The first class that our Springified Hello World example needs is a service class whose purpose is to print the infamous greeting. Listing 1.1 shows GreetingService.java, an interface that defines the contract for our service class.

Listing 1.1 The GreetingService interface separates the service's implementation from its interface.

package com.springinaction.chapter01.hello;

public interface GreetingService {
   public void sayGreeting();
}

GreetingServiceImpl.java (listing 1.2) implements the GreetingService interface. Although it's not necessary to hide the implementation behind an interface, it's highly recommended as a way to separate the implementation from its contract.

Listing 1.2 GreetingServiceImpl.java: Responsible for printing the greeting

package com.springinaction.chapter01.hello;

public class GreetingServiceImpl implements GreetingService {
   private String greeting;

   public GreetingServiceImpl() {}

   public GreetingServiceImpl(String greeting) {
      this.greeting = greeting;
   }

   public void sayGreeting() {
      System.out.println(greeting);
   }

   public void setGreeting(String greeting) {
      this.greeting = greeting;
   }
}

The GreetingServiceImpl class has a single property: the greeting property. This property is simply a String that holds the text that is the message that will be printed when the sayGreeting() method is called. You may have noticed that the greeting can be set in two different ways: by the constructor or by the property's setter method.

What's not apparent just yet is who will make the call to either the constructor or the setGreeting() method to set the property. As it turns out, we're going to let the Spring container set the greeting property. The Spring configuration file (hello.xml) in listing 1.3 tells the container how to configure the greeting service.

Listing 1.3 Configuring Hello World in Spring

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
   "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
   <bean id="greetingService"
         class="com.springinaction.chapter01.hello.GreetingServiceImpl">
      <property name="greeting">
         <value>Buenos Dias!</value>
      </property>
   </bean>
</beans>

The XML file in listing 1.3 declares an instance of a GreetingServiceImpl in the Spring container and configures its greeting property with a value of "Buenos Dias!" Let's dig into the details of this XML file a bit to understand how it works.

At the root of this simple XML file is the <beans> element, which is the root element of any Spring configuration file. The <bean> element is used to tell the Spring container about a class and how it should be configured. Here, the id attribute is used to name the bean greetingService and the class attribute specifies the bean's fully qualified class name.

Within the <bean> element, the <property> element is used to set a property, in this case the greeting property. By using <property>, we're telling the Spring container to call setGreeting() when setting the property.

The value of the greeting is defined within the <value> element. Here we've given the example a Spanish flair by choosing "Buenos Dias" instead of the traditional "Hello World."

The following snippet of code illustrates roughly what the container does when instantiating the greeting service based on the XML definition in listing 1.3:2

GreetingServiceImpl greetingService = new GreetingServiceImpl();
greetingService.setGreeting("Buenos Dias!");

Similarly, we may choose to have Spring set the greeting property through GreetingServiceImpl's single argument constructor. For example:

<bean id="greetingService"
      class="com.springinaction.chapter01.hello.GreetingServiceImpl">
   <constructor-arg>
      <value>Buenos Dias!</value>
   </constructor-arg>
</bean>

The following code illustrates how the container will instantiate the greeting service when using the <constructor-arg> element:

GreetingServiceImpl greetingService =
   new GreetingServiceImpl("Buenos Dias");

The last piece of the puzzle is the class that loads the Spring container and uses it to retrieve the greeting service. Listing 1.4 shows this class.

Listing 1.4 The Hello World main class

package com.springinaction.chapter01.hello;

import java.io.FileInputStream;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;

public class HelloApp {
   public static void main(String[] args) throws Exception {
      BeanFactory factory =
         new XmlBeanFactory(new FileInputStream("hello.xml"));

      GreetingService greetingService =
         (GreetingService) factory.getBean("greetingService");

      greetingService.sayGreeting();
   }
}