Ask a question
Monday, 14 September 2009 12:02
Agile - Overview of Spring Framework
-
font size
decrease font size
increase font size
What Is Spring?
When people ask me what Spring does, I have to stop and think about how to answer it in one sentence, which is not easy to do as you will see shortly. So, let me first start by quoting an excerpt directly out of the Spring Framework Reference Documentation (springframework.org) because it describes the framework well:
"...Spring provides a light-weight solution for building enterprise-ready applications, while still supporting the possibility of using declarative transaction management, remote access to your logic using RMI or web services, mailing facilities and various options in persisting your data to a database. Spring provides an MVC framework, transparent ways of integrating AOP into your software and a well-structured exception hierarchy including automatic mapping from proprietary exception hierarchies.
Spring could potentially be a one-stop shop for all your enterprise applications, however, Spring is modular, allowing you to use parts of it, without having to bring in the rest..."
Let's explore the "modular" aspect of Spring a bit further. Figure 6.1 (also taken directly out of the Spring Framework Reference Documentation) is probably the best way to get an immediate understanding of the various things Spring can do, and it shows precisely why it is difficult to describe the entire Spring Framework in a short sentence.


Spring Packaging for Development
The Spring modules, shown in Figure 6.1, are essentially conceptual groups of functionality provided by the extensive list of Spring's Java packages and underlying classes.
Figure 6.2 shows the various top-level Spring packages. (Note:The shaded packages are ones we will use for our sample application, again demonstrating that Spring does not take an all-or-nothing approach.)

Overwhelmed by the Size of the Spring Framework?
The Spring Framework contains something along the lines of 130+ Java packages and 1,200+ Java classes. However, do not be overwhelmed by this number; here is why.
First, you may want to use only Spring's IoC features, so you could essentially ignore most of the APIs. Second, although there are lots of classes and there's lots of Javadoc, many of these classes are for internal use by the framework itself. Third, Spring enables you to select the modules you want to use and ignore the rest. For example, we will use only a handful of these for our sample application, Time Expressionthis is proof that Spring's design is highly modular.
Spring Packaging for Deployment
The modular aspect of Spring extends to deployment as well, because you can deploy your application with only the subset of Spring JAR files you need (for example, spring-jdbc.jar). Table 6.1 shows how Spring provides the packages using various JAR files. Notice how the spring.jar is bigger than others, because it is the complete package. I tend to include the complete spring.jar file in my applications because 1.7MB isn't considered very large these days, especially for server-side applications.

Overview of the Spring Modules
Now that we have seen a very high-level preview of Spring, let's look at a brief description of each module. First, we will begin with the two most important modules and then look at the remaining ones in an alphabetical order. Again, we will use only a subset of the modules described next, so do not get overwhelmed by how extensive this framework is.
Spring Core
The core module is essentially the foundation for Spring. It provides fundamental features such as dependency injection (which we will look at later in the chapter) and management of beans. Some of the top-level packages that fit under this module are org.springframework.beans, org.springframework.core, and org.springframework.util.
Spring Context
The context module is perhaps the second most important module in Spring, after the Spring Core module. It contains key classes such as ApplicationContext (explained later in this chapter) and WebApplicationContext, which we will use in Time Expression (loaded from our timex-servlet.xml file, which is explained in the next chapter). In addition, we will use the org.springframework.mail (for sending emails) and org.springframework.validation (for validating web UI fields) packages, which are also considered part of this module.
Other packages, primarily used for remote/distributed functionality (EJB and JNDI, for example), are outside the scope of this book.
Spring AOP
We will not write AOP code directly using Spring. However, indirectly we will end up using Spring AOP-based facilities, such as interceptors for our web application and declarative transaction management. In fact, the Spring reference documentation mentions the same point; that is, if the prepackaged functionality provided in Spring is sufficient for your needs, you do not need to use Spring AOP (to write custom aspects, for example).
Spring DAO
Because we are already using Hibernate for database persistence, we do not need this module. However, this module is worth checking out if you like, or need, to work with JDBC but don't like all the tedious try-catch-finally blocks, opening/closing connections, and more. In addition, Spring goes one step further by providing a consistent exception hierarchy, which can convert vendor-specific checked exceptions into more consistent runtime exceptions that can be caught only in the layer of your application you want and ignore it in other places (thereby eliminating the need for cumbersome try/catch/finally code blocks).
Spring for Persistence
It is important to realize that Spring provides a complete persistence functionality. In other words, you could use Spring without an ORM product such as Hibernate and still get the benefits of an easier and cleaner persistence mechanism than plain JDBC (although it won't provide some of the benefits of ORM frameworks that we discussed in Chapter 5, "Using Hibernate for Persistent Objects").
In addition, you get a consistent exception-handling mechanism and other related benefits. We are using ORM framework because so we can work with database records as Java objects.
Spring ORM
Spring's Object-Relational Map (ORM) module provides integration support for popular ORM products used by Java developers, such as Hibernate, JDO, Oracle TopLink, Apache OJB, and iBATIS SQL Maps.
Some of the benefits of using Spring's ORM support include ease of testing (via dependency injection), common data exceptions, persistent resource management (for example, Hibernate's SessionFactory), integrated enterprise-class transaction management, and more.
Spring Web and Web MVC
Among all the Spring modules mentioned here, the web modules are where we will spend the most time in this book. However, we will work with only a few of the classes and packages. For example, we will not have a need for packages that support Sun Microsystem's JavaServer Faces (JSF) standard and others.
Some examples of classes found in these packages, and applicable to Time Expression, are SimpleUrlHandlerMapping, InternalResourceViewResolver, SimpleFormController, Validator, and many others. We will look at these and other classes in more detail in the next chapter.
Where Spring Framework Fits into Our Architecture
Before discussing the various benefits and concepts of Spring, it is a good idea to revisit our architecture diagram (from Chapter 3, "XP and AMDD-Based Architecture and Design Modeling") to see where we will use Spring. Figure 6.3 shows the diagram. Notice that we will use Spring web controllers (discussed in detail in Chapter 7, "The Spring Web MVC Framework"), job scheduling, sending emails (in Chapter 10), and more. At the core of our application, we will use Spring's IoC services.

Benefits of Using Spring
By now, you should have a pretty good idea about what Spring is, how it is logically organized (into modules), and the types of functionality it provides. Although the benefits may appear somewhat obvious, the following is an explicit list:
· POJOs My favorite benefit is that Spring enables me to develop enterprise-class applications using POJOs. The benefit of using only POJOs is that you do not need an EJB container product such as an application server if your application doesn't require all the capabilities that such products provide. With Spring, you have the option of using only a robust servlet container such as Tomcat or some commercial product.
· Modular As we have already discussed, Spring is organized in a modular fashion. Even though the number of packages and classes is substantial, you have to worry only about ones you need (see the sidebar "Overwhelmed by the Size of the Spring Framework?"). Hence, phasing Spring into an existing or new project can be done on a case-by-case and module-by-module basis.
· Complementary I like the fact that Spring does not reinvent the wheel; instead, it truly complements some of the existing work out there. For example, it complements several ORM frameworks, JEE, Quartz and JDK timers, other view technologies, and more.
· Testing Testing an application written with Spring is simple because environment-dependent code is moved into this framework (versus JNDI lookups embedded in code, for example). Furthermore, by using JavaBean-style POJOs, it becomes easier to use dependency injection for injecting test data (perhaps by using an XML file as the source of test data). In addition, Spring's mock classes can help you simulate classes such as an HTTP request object. This is primarily true because dependency injection works with setter and getter methods. Hence it is easy to inject test data into your objects and unit test your code using a product such as JUnit. This also includes testing of web components developed using Spring's web MVC framework, as you will see in the next chapter.
· Singletons Spring eliminates the need to maintain your own singleton classes. Instead, you write a class as a normal POJO (without the need for static variables/methods), and Spring ensures that you always get access to the same object, unless you override the default by defining a class as nonsingleton.
· Web framework Spring's web framework is a well-designed web MVC framework, which provides a great alternative to web frameworks such as Struts or other overengineered or less popular web frameworks. It enables you to develop no-form screens, simple-form screens, wizardlike screens, and much more. It can also bind HTML form fields directly to the business objects instead of having to write custom classes that extend the web framework's classes. Spring Web MVC is also view agnostic, so it can work with JavaServer Pages (JSP), Velocity, JavaServer Faces (JSF), and others. In addition, the Spring Web Flow subproject can be used to develop web applications that require state management across several HTTP requests (an online airline-booking website, for example).
· Consistent exception hierarchy Spring provides a convenient API to translate technology-specific exceptions (thrown by JDBC, Hibernate, or JDO, for example) into consistent, unchecked exceptions (org.springframework.dao. PessimisticLockingFailureException, for example).
· Enterprise-class transaction management Spring provides a consistent transaction management interface that can scale down to a local transaction (using a single database, for example) and scale up to global transactions (using JTA, for example). Spring also provides application server-specific integration, for instance, with BEA's WebLogic Server and IBM's WebSphere. Spring's transaction management can be used programmatically or declaratively. We will use the declarative version in Chapter 10.
· Lightweight container IoC containers tend to be lightweight, especially when compared to EJB containers, for example. This can be beneficial, perhaps for developing and deploying applications on computers with limited memory and CPU resources.
We saw some of the benefits here, particularly ones that are applicable to Time Expression. However, if you decide to use Spring more extensively, you are likely to come up with your own list of benefits.
Fundamental Spring Concepts
We have covered a lot of introductory material on Spring already. However, this only reflects what Spring can do for you and how it is organized. We still need to cover some basic concepts that Spring is built on. Let's do that now before jumping into Spring code related to Time Expression (in the next chapter).
Dependency Injection Pattern (and IoC Containers)
In 2004, Martin Fowler published an article (http://www.martinfowler.com/articles/injection.html) discussing inversion of control (IoC) containers. Martin Fowler, some people involved with the PicoContainer, Rod Johnson (founder of the Spring Framework), and others collectively defined the dependency injection pattern. Dependency injection is a style of IoC; another style uses a template/callback technique. In both cases you are giving control to something else (hence, the term inversion of control). We will, of course, use the dependency injection style.
What is dependency injection exactly? Let's look at these two words separately. First, there is the dependency part; this basically translates into an association between two classes. For example, class A might need class B to get its job done. In other words, class A is dependent on class B. Now, let's look at the second part, injection. All this means is that class B will get injected into class A by the IoC container. This injection can happen in the way of passing parameters to the constructor or by post-construction using setter methods. (Both are described in more detail later in this chapter.)

Figure 6.4 shows an association between two classes we will see in our examples for Time Expression (in the next chapter). The associations shown in this diagram are exactly the dependencies we will map in the Spring application context file. In other words, TimesheetListController depends on TimesheetManager; hence, we will use Spring to automatically create a single instance of the TimesheetManager and inject (set) it via the TimesheetListController.setTimesheetManager method.
You might not be fully convinced of the benefits of using the design pattern approach for developing applications. However, after you begin working in this fashion, you probably won't want to go back to constructing objects using new statements, which not only clutters your Java code more than using dependency injection, but also couples your associated classes a bit more.
Two Injection Styles
There are two key types of dependency injection styles: one via arguments passed to the constructor when an object is created and the other via the setter methods of a JavaBean style class, after the object has been created.
Spring advocates the use of setter-based dependency injection (in the Spring Reference Documentation), because passing many arguments to the constructor can get cumbersome. Martin Fowler, on the other hand, argues (also at http://www.martinfowler.com/articles/injection.html) that if you have too many constructor arguments, your object might be too busy, and it's worth considering splitting the class up.
Although there are pros and cons to both approaches, considering that we are using Spring, we will go with Spring's recommendation and accordingly use setter-based injection for Time Expression. Also, I prefer the JavaBean style of injecting and obtaining property valuesthat is, using setters and getters. For some reason, this feels a bit more natural to me while coding in Java, but you might disagree. To further confuse things, the Pico Container team prefers the constructor-based injection and provides some valid reasons for it on their website (http://www.picocontainer.org/Why+Constructor+Injection).
Either way, it is nice to know that Spring supports both styles, which we will review shortly.
Beans, BeanFactory, and ApplicationContext
The org.springframework.beans.factory.BeanFactory interface is the actual IoC container! It is an interface that essentially manages the application's configuration by instantiating and managing beans defined via code or, in our case, XML files. Beans can be any type of objects, but commonly are JavaBean style classesthat is, classes with getters and setters.
The org.springframework.context.ApplicationContext essentially extends BeanFactory and adds additional facilities such as resource bundles, integration with Spring AOP, message resource handling, event broadcasting, and more. Furthermore, WebApplicationContext extends ApplicationContext by adding web application-specific context. Although you can use an implementation of the BeanFactory interface (for example, XmlBeanFactory), it is recommended that you use ApplicationContext for server-side applications.
This book's code zip file shows springtest-applicationcontext.xml, a sample Spring application context file. This example demonstrates both the setter-based injection using the
class="com.visualpatterns.timex.test.SpringTestMessage"
lazy-init="false" init-method="printMessage">
Notice also that we have an initialization method using the init-method attribute; this is a nice way to invoke initialization and termination methods on objects. This relationship (or association) is established using the
element and the injection occurs via the SpringTestMessage.setMessage method, as shown here:
public void setMessage(String message)
{
this.message = message;
}
Our SpringTest.java class (also in the book's code zip file) shows how simple it is to load an entire application context file and immediately begin using the various beans, with all the collaborator classes autowired by Spring's IoC container, as demonstrated here:
public static void main(String args[]) throws Exception
{
FileSystemXmlApplicationContext factory =
new FileSystemXmlApplicationContext(
"src/conf/springtest-applicationcontext.xml");
SpringTestMessage stm = (SpringTestMessage) factory
.getBean("springtestmessage");
}
Before we move to the next section, the following list describes a couple of additional notes about beans:
· Beans can be created by Spring via the constructor (as you normally would using a new statement) or via static factory methods of another class.
· Each bean must have a unique id (for example, springtestmessage).
· Beans can be of two types, Singleton and Prototype (nonsingleton). By default, all beans are singletons, but you can make them prototypes by specifying an attribute such as singleton="false". We will use only singletons for Time Expression because Spring cannot manage the life cycle of a prototype bean after it has been created and handed off to (injected in) the objects that depend on it. Also, by specifying singleton="false" for a given bean definition, you are instructing Spring to create a new instance of the bean every time there is a request for this bean. Last, almost 100% of the time, using singleton beans is sufficient.
· You can inject values in a setter method or constructor as single objects or as collection elements (for example, List, Set, Map, and Properties).
This is all we will discuss about BeanFactory and ApplicationContext classes in this chapter. After we move to the Spring Web MVC Framework (in the next chapter), we will not have to worry about creating either of these objects manually.
However, you might want to familiarize yourself a bit more about how all this works by reading the Spring Reference Documentation (springframework.org). For example, you might want to better understand constructor argument resolution, dependency checking, autowiring of collaborator beans, programmatically interacting with the BeanFactory, injecting null values, method-based injection, and much more. You will also see additional examples of several of these things in the next chapter and in later chapters in this book.
The spring-beans.xsd (or the older spring-beans.dtd) file provides the XML schema for the Spring Framework's application context file. Looking at one of these files in the Spring's software directories might give you some additional insight into the various elements and properties that can be specified in the application context file.
Property Editors
Spring makes heavy use of the java.beans.PropertyEditor interface by allowing custom property editors to be registered, which convert an object into readable text, and vice versa. For example, in the next chapter, we will use it to convert the hours entered on our Enter Hours web page.
Spring Subprojects
Just when you thought you had heard enough about Spring, there is more.
What we have looked at so far are modules and packages that are part of the Spring's core distribution. There are also other subprojects hosted by the Spring team that can be found via the springframework.org website:
· Acegi Security System for Spring This project provides comprehensive security services for the Spring Framework (for example, HTTP security, object instance security, security taglib, password encoding, and more).
· Spring BeanDoc This tool facilitates documentation and graphing of a Spring application's bean factories and application context file. A very useful, easy, and flexible tool to use.
· Spring IDE for Eclipse This is a graphical user interface for the configuration files used by a Spring-based application. We will see a preview of this in Chapter 8, "The Eclipse Phenomenon!"
· Spring Rich Client I have not personally worked with this project, so I will quote the Spring website, which claims that this is a "viable option for developers that need a platform and a 'best-practices' guide for constructing Swing applications quickly."
· Spring Web Flow This project is based on the concepts similar to the Spring Web MVC Framework, essentially providing wizardlike screen functionality to implement a business process. This project has been getting a lot of attention recently and is worth checking out if you need the type of functionality it provides.
Read 373 times
Published in
Java