< Day Day Up > |
8.1 What Is Spring?Spring is an open source framework intended to make J2EE development easier. It consists of a container, a framework for configuring and assembling components, and a set of snap-in services for transactions, persistence, and web user interfaces. The container itself is small—only 90 KB. The entire framework is much larger, but it does a marvelous job of shielding that size and complexity from you using many of the principles in this book. It's a mind-bending framework, but in a good way. You'll find that once you learn to give away a whole lot of control, you also lose a lot of tedious, repetitive detail, simultaneously gaining elegance and simplicity. Here's how to build something in Spring:
You'll see a concrete example shortly, but bear with me. Since Spring is so different from most J2EE programming styles, you need a firm foundation before you dive in. The centerpiece of Spring is the XML bean factory, a framework that uses independent beans and configuration to assemble an application. Alternatively, Spring can make many connections without configuration information through the autowiring option. For example, if your application needs a data source and you only specified one kind of data source, you can let Spring autowire that connection. Atop these factories and configuration services, Spring snaps in some services. Most of them are simple, high-level abstractions that rely on J2EE services or other lower-level frameworks to do the work. These are the major frameworks now supported by Spring:
You don't have to adopt any of these services to use Spring. Further, unlike EJB, you can adopt them piecemeal or extend them as needed to accomplish your goals. For the most part, the authors of Spring relied on existing frameworks to snap into Spring. They provided the underpinnings and additional abstractions to simplify a few services as needed. The real power is in the approach. The single exception is the MVC web framework, which directly competes with a number of viable alternatives. Spring is part of a growing trend toward lightweight containers. It's easy to see the contrast between this approach and heavier containers:
The contrast, on the surface, is staggering. Build applications with both models, and you'll find that lightweight containers do more than save you from tedious details. They change the way that you think; they change the way that you test. In short, they change the way that you program from the inside out. The "secret sauce" combines two ingredients, dependency injection (described in Chapter 6) and inversion of control. 8.1.1 Inversion of ControlEarlier in the book, we discussed how modern developers get tremendous benefit by changing who's in control. Most applications hardwire services to objects or components that use the service. If you choose to code this way, you're choosing to couple your code, with all of the inherent disadvantages. Certainly, sometimes, you'll still want to directly call a service. After all, what is a method call? Sometimes, though, you want to break all dependencies between the caller and the service. In the passive domain models in Chapter 3, you saw how to get more power and flexibility from an architecture that changes who is in control: specifically, control passes from your application to the framework. This idea is not new. Older applications used to control the navigation between screens of an application. When I worked at IBM in the late 1980s, we had a team of four working full time on the navigation for a query report writer. When we started building graphical user interfaces, control passed from the application to the graphical user interface framework. We stripped out our navigator component and replaced the navigator team with one part-time developer. That's the power of inversion of control. Although lightweight containers use inversion of control broadly, inversion of control alone is not what makes them different. Within a lightweight container, inversion of control focuses on one particular aspect of the application: configuration and assembly through dependency injection. Rely on configuration rather than a hard-wired method call and trust the framework to wire your application together. A single assembler reads your configuration file, creates the beans that you've defined, and then initializes them, wiring them together in the process. Figure 8-1 repeats the dependency injection figure from Chapter 6 (Figure 6-8). The job of creating objects and setting the properties appropriately passes from the more traditional application to the framework provided by the lightweight container. In the process, the container satisfies two dependencies: the dependency of the data source on its configuration and the dependency of the DAO on a data source. The coupling moves from code to configuration. Singletons disappear. You simply write the class and configuration and the framework creates and assembles instances to form an application. Figure 8-1. Lightweight inversion of control containers |
< Day Day Up > |