October 2003
Discuss this Article
You may have heard the buzz this summer around the Spring Framework. In this article, I’ll try to explain what Spring sets out to achieve, and how I believe it can help you to develop J2EE applications.
Yet another framework?
You may be thinking "not another framework." Why should you bother to read this article, or download the Spring Framework, when there are already many open source (and proprietary) J2EE frameworks?
I believe that Spring is unique, for several reasons:
• It addresses areas that many other popular frameworks don’t. Spring focuses around providing a way to manage your business objects.
• Spring is both comprehensive and modular. Spring has a layered architecture, meaning that you can choose to use just about any part of it in isolation, yet its architecture is internally consistent. So you get maximum value from your learning curve. You might choose to use Spring only to simplify use of JDBC, for example, or you might choose to use Spring to manage all your business objects.
• It’s designed from the ground up to help you write code that’s easy to test. Spring is an ideal framework for test driven projects.
Spring is not necessarily one more framework dependency for your project. Spring is potentially a one-stop shop, addressing most infrastructure concerns of typical applications. It also goes places other frameworks don’t. Although it has been an open source project only since February 2003, Spring has a long heritage. The open source project started from infrastructure code published with my book, Expert One-on-One J2EE Design and Development, in late 2002. Expert One-on-One J2EE also laid out the basic architectural thinking behind Spring. However, the architectural
concepts go back to early 2000, and reflect my experience in developing infrastructure for a series of successful commercial projects.
Since January 2003, Spring has been hosted on SourceForge. There are now ten developers, of who
m six are highly active.
Architectural benefits of Spring
Before we get down to specifics, let’s look at some of the benefits Spring can bring to a project:
• Spring can effectively organize your middle tier objects, whether or not you choose to use EJB. Spring takes care of plumbing that would be left up to you if you use only Struts or other frameworks geared to particular J2EE APIs.
• Spring can eliminate the proliferation of Singletons seen on many projects. In my experience, this is a major problem, reducing testability and object orientation.
• Spring can eliminate the need to use a variety of custom properties file formats, by handling configuration in a consistent way throughout applications and projects. Ever wondered what magic property keys or system properties a particular class looks for, and had to read the Javadoc or even source code?
With Spring you simply look at the class’s JavaBean properties. The use of Inversion of Control (discussed below) helps achieve this simplification.
• Spring can facilitate good programming practice by reducing the cost of programming to interfaces, rather than classes, almost to zero.
• Spring is designed so that applications built with it depend on as few of its APIs as possible. Most business objects in Spring applications have no dependency on Spring.
• Applications built using Spring are very easy to unit test.
• Spring can make the use of EJB an implementation choice, rather than the determinant of application architecture. You can choose to implement business interfaces as POJOs or local EJBs without affecting calling code.
• Spring helps you solve many problems without using EJB. Spring can provide an alternative to EJB that’s appropriate for many web applications. For example, Spring can use AOP to deliver declarative transaction management without using an EJB container; even without a JTA implementation, if you only need to work with a single database.
• Spring provides a consistent framework for data access, whether using JDBC or an O/R mapping product such as Hibernate.
Spring really can enable you to implement the simplest possible solution to your problems. And that’s worth a lot.
What does Spring do?
Spring provides a lot of functionality, so I’ll quickly review each major area in turn.
Mission statement
Firstly, let’s be clear on Spring’s scope. Although Spring covers a lot of ground, we do have clear vision as to what it should and shouldn’t address.
Spring’s main aim is to make J2EE easier to use and promote good programming practice.
Spring does not reinvent the wheel. Thus you’ll find no logging packages in Spring, no connection pools, no distributed transaction coordinator. All these things are provided by open source projects (such as Commons Logging, which we use for all our log output, or Commons DBCP), or by your application server. For the same reason, we don’t provide an O/R mapping layer. There are good solutions to this problem such as Hibernate and JDO. Spring does aim to make existing technologies easier to use. For example, although we are not in the business of low-level transaction coordination,
we do provide an abstraction layer over JTA or any other transaction strategy.
Spring doesn’t directly compete with other open source projects unless we feel we can provide something new. For example, like many developers, we have never been happy with Struts, and feel that there’s room for improvement in MVC web frameworks. In some areas, such as its lightweight IoC container and AOP framework, Spring does have direct competition, but these are areas in which no solution has become popular. (Spring was a pioneer in these areas.)
Spring also benefits from internal consistency. All the developers are singing from the same hymn sheet, the fundamental ideas remaining faithful to those of Expert One-on-One J2EE Design and Development. And we’ve been able to use some central concepts, such as Inversion of Control, across multiple areas.
Spring is portable between application servers. Of course ensuring portability is always a challenge, but we avoid anything platform-specific or non-standard, and support users on WebLogic, Tomcat, Resin, JBoss, WebSphere and other application servers.
Inversion of control container
The core of Spring’s design is the org.springframework.beans package, designed for working with JavaBeans. This package typically isn’t used directly by users, but serves as the underpinning of much of the other functionality.
The next higher layer of abstraction is the "Bean Factory." A Spring bean factory is a generic factory that enables objects to be retrieved by name, and which can manage relationships between objects.
Bean factories support two modes of objects:
• "Singleton": in this case, there’s one shared instance of the object with a particular name, which will be retrieved on lookup. This is the default, and most often used, mode. It’s ideal for stateless service objects.
• "Prototype": in this case, each retrieval will result in the creation of an independent object. For example, this could be used to allow each user to have their own object.
As org.springframework.beans.factory.BeanFactory is a simple interface, it can be implemented for a range of underlying storage methods. You could easily implement your own, although few users find they need to. The most commonly used BeanFactory definitions are:
• The XmlBeanFactory. This parses a simple, intuitive XML structure defining the classes and properties of named objects. We provide a DTD to make authoring easier.
• ListableBeanFactoryImpl: This provides the ability to parse bean definitions in properties files, and create BeanFactories programmatically.
Each bean definition can be a POJO (defined by class name and JavaBean initialisation properties), or a FactoryBean. The FactoryBean interface adds a level of indirection. Typically this is used to create proxied objects using AOP or other approaches: for example, proxies that add declarative transaction management. (This is similar to EJB interception in concept, but works out much simpler in practice.)
BeanFactories can optionally participate in a hierarchy, "inheriting" definitions from their ancestors. This enables the sharing of common configuration across a whole application, while individual resources such as controller servlets also have their own independent set of objects.
This motivation for the use of JavaBeans is described in Chapter 4 of Expert One-on-One J2EE Design and Development, which is available on the ServerSide as a free PDF (/articles/article.tss?l=RodJohnsonInterview).
Through its BeanFactory concept, Spring is an Inversion of Control container. (I don’t much like the term container, as it conjures up visions of heavyweight containers such as EJB containers. A Spring BeanFactory is a container that can be created in a single line of code, and requires no special deployment steps.)
The concept behind Inversion of Control is often expressed in the Hollywood Principle: "Don’t call me, I’ll call you." IoC moves the responsibility for making things happen into the framework, and away from application code. Where configuration is concerned this means that while in traditional container architectures such as EJB, a component might call the container to say "where’s object X, which I need to do my work", with IoC the container figures out that the component needs an X object, and provides it to it at runtime. The container does this figuring out based on method signatures (such as JavaBean properties) and, possibly, configuration data such as XML.
IoC has several important benefits. For example:
• Because components don’t need to look up collaborators at runtime, they’re much simpler to write and maintain. In Spring’s version of IoC, components express their dependency on other components via exposing JavaBean setter methods. The EJB equivalent would be a JNDI lookup, which requires the developer to write code.
• For the same reasons, application code is much easier to test. JavaBean properties are simple, core Java and easy to test: just write a self-contained JUnit test method that creates the object and sets the relevant properties.
• A good IoC implementation preserves strong typing. If you need to use a generic factory to look up collaborators, you have to cast the results to the desired type.
This isn’t a major problem, but it is inelegant. With IoC you express strongly typed dependencies in your code and the framework is responsible for type casts. This means that type mismatches will be raised as errors when the framework configures the application; you don’t have to worry about class cast exceptions in your code.
• Most business objects don’t depend on IoC container APIs. This makes it easy to use legacy code, and easy to use objects either inside or outside the IoC container. For example, Spring users often configure the Jakarta Commons DBCP DataSource as a Spring bean: there’s no need to write any custom code
spring out 是什么意思to do this. We say that an IoC container isn’t invasive: using it won’t invade your code with dependency on its APIs. Any JavaBean can become a component in
a Spring bean factory.
This last point deserves emphasis. IoC is unlike traditional container architectures, such as EJB, in this minimization of dependency of application code on container. This means that your business objects can potentially be run in different IoC frameworks - or outside any framework - without code changes.
In my experience and that of Spring users, it’s hard to overemphasize the benefits that IoC brings to application code.
IoC is not a new concept, although it’s only just made prime time in the J2EE community. There are alternative IoC containers: notably, Apache Avalon, PicoContainer and HiveMind. Avalon has never become particularly popular, although it is powerful and has a long history. Avalon is fairly heavyweight and complex, and seems more invasive than newer IoC solutions. PicoContainer is lightweight and emphasizes the expression of dependencies through constructors rather than JavaBean properties. Unlike Spring, its design allows the definition of only one object of each type (possibly a limitation resulting from its rejection of any metadata outside Java code). For a comparison between Spring and PicoContainer and other IoC frameworks, see the article "The Spring Framework - A Lightweight Container" on the Spring website at
/docs/lightweight_container.html. This page includes a link to the PicoContainer website.
Spring BeanFactories are very lightweight. Users have successfully used them inside applets, as well as standalone Swing applications. (They also work fine within an EJB container.) There are no special deployment steps and no detectable startup time. This ability to instantiate a container almost instantly in any tier of an application can be very valuable.
The Spring BeanFactory concept is used throughout Spring, and is a key reason that Spring is so internally consistent. Spring is also unique among IoC containers in that it uses IoC as a basic concept throughout a
full-featured framework.
Most importantly for application developers, one or more BeanFactories provide a well-defined layer of business objects. This is analogous to, but much simpler than, a layer of local session beans. Unlike EJBs, the objects in this layer can be interrelated, and their relationships managed by the owning factory. Having a well-defined layer of business objects is very important to a successful architecture.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。