One of the best reasons for using Spring is that it makes designing and building an application using traditional OOP practices much simpler than when you are using standard J2EE features. With Spring, you are free to design your applications as you see fit and have Spring worry about wiring the different components together. Spring removes the need for false patterns, such as Factory and Singleton, that hinder testing and do not solve the problems for which they are designed half as well as they would like.
In this section, we present a high-level overview of the design and implementation decisions of the SpringBlog application with pointers to where each topic is discussed in detail.
The design of SpringBlog is very simple, with each tier defined in terms of interfaces rather than concrete classes. In each tier, the interfaces that correspond to that tier define only the methods exposed by that tier to other tiers classified as client tiers; no methods or properties are used to configure parameters. Instead, the configuration methods are declared on the classes that implement the interfaces in each tier and configuration data is injected using Spring's IoC-based configuration mechanisms. Chapter 11 presents a full discussion of the different interfaces that make up SpringBlog, how they are wired together using Spring, and factors affecting interface granularity. In particular, when we discuss decoupling the auditing functionality from the main blog functionality, you will see an example of how increasing the interface granularity improves application testability.
The SpringBlog application also contains a basic Domain Object Model (DOM) that encapsulates both data and behavior. In Chapter 11, we take the time to look at the different flavors of the DOM you may have seen in projects that you have worked on, and we discuss the factors you must consider when deciding whether to encapsulate behavior in the DOM or in separate service objects.
Data access is a topic close to many developers' hearts and it is often the subject of many heated discussions on developer forums across the Internet. In recent times, the focus in the Java world has been on Object-Relational Mapping (ORM) tools as a replacement for JDBC, which many see as an overcomplicated mess. A big part of Spring's feature set lies in its support for data access technologies. All in all, Spring supports five different data access mechanisms: plain JDBC, Hibernate, iBATIS, Java Data Objects (JDO), and Apache ObJect Relational Bridge (OJB).
With the SpringBlog application, we wanted to show how easy it is to switch between data access implementations, so we built three different implementations of the Data Access Tier: one using JDBC, one using Hibernate, and a third using iBATIS.
Spring's support for JDBC is fantastic, removing the need for much of the spaghetti code that was required when using JDBC directly to catch and handle Exceptions correctly. In Chapter 8, you will see how to use Spring to simplify your JDBC code; in that chapter, we also present some patterns for maximizing JDBC reuse across multiple database systems.
Hibernate is perhaps the most well-known ORM tool in the Java world, and it has enjoyed considerable success due to the ease with which it can be used to develop high-performance data access code. Although Hibernate has quite a simple API, the error-handling code you need to use Hibernate is quite verbose; Spring simplifies this greatly, reducing most Hibernate operations to just a single line of code. Chapter 9 discusses Spring's support for Hibernate and how we use Spring and Hibernate to build the second implementation of our Data Access Tier.
Strictly speaking, iBATIS is not an ORM tool in that it does not remove all responsibility from the developer for creating the SQL statements needed to map Java objects to data in the RDMBS. Instead, iBATIS introduces the concept of a SQL map, allowing you to specify a variety of SQL queries and how these queries map to both input and output parameters. iBATIS is incredibly powerful and is the personal favorite of both authors. Chapter 10 discusses iBATIS in detail and shows how we built our third data access implementation.
In all cases, we use Spring's infrastructure classes for each data access tool. These classes integrate with Spring's transaction architecture, which allows transactions to be managed in a platform- and resource-provider-independent way in the Business Tier of the SpringBlog application.
The SpringBlog application is fairly simple, and aside from the basic storage and retrieval of blog data, there are very few business rules in the system. However, there are two particular business functions in the SpringBlog application that exploit two of the most interesting Spring features: the AOP-based obscenity filter and the audit log.
AOP is a hot topic in the Java world at the moment and as a result, Java developers are fortunate to have a wide range of different AOP implementations available to them. Spring AOP support comes in two forms: the Spring native AOP framework and integration with the AspectJ AOP framework. 7 discuss both Spring AOP and AspectJ integration in detail.
For the SpringBlog application, we wanted to provide a practical example of AOP usage rather than the traditional (and boring) logging example. One of the features that we were working on for the sample application was an obscenity filter, and during design, it became apparent that AOP was the ideal mechanism for implementing this filter. In Chapter 7, you will see how we built the obscenity filter and how we used AOP to apply the filter selectively to methods on the core business interface, BlogManager.
As developers, one of the features of Spring that we found most impressive was the transaction support. Spring's transaction support provides a simple mechanism to control transactions across one or more resource providers, either programmatically or declaratively. Chapter 13, you can see how you can use the same transaction architecture to manage JMS transactions.
For the SpringBlog application, we defined a requirement that all operations in the blog be audited and logged to the database. To ensure that an operation is rolled back if the audit process fails, we used the Spring transaction framework to encapsulate each operation and its audit process in a single transaction. We discuss this in Appendix A demonstrates the technique we used to test to make sure the transaction rollback was functioning correctly.
As with support for data access technologies, Spring is well known for its support for a wide range of different web application frameworks and tools. Chapters 17–19 provide a detailed discussion of the Spring MVC framework, the different view technologies used by Spring, and Spring/Struts integration.
In keeping with the multiple implementations available for the Data Access Tier, we built two implementations for the Web Tier, one using Spring MVC and the other using Struts. In
With most web applications, only a portion of the screen changes each time a new request is processed, and common elements such as the header and navigation bar remain the same. Using Tiles, you can assemble your pages from individual parts called tiles, enabling common elements to be defined once and reused across the application. Chapter 18 looks at using Tiles with a Spring application and shows how we used Tiles to build the sample application.
Nowadays it is uncommon for web applications to be restricted to purely HTML content; other content types such as PDF and Microsoft Excel are becoming more prevalent. Also, it is not uncommon to see other frameworks such as FreeMarker and Velocity used to produce text-based content. In Chapter 18, you will see how to use a variety of different view technologies with Spring and how we used these technologies in the SpringBlog application.