963 lines
45 KiB
XML
963 lines
45 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<chapter id="overview">
|
|
<title>Introduction to Spring Framework</title>
|
|
|
|
<para>Spring Framework is a Java platform that provides comprehensive
|
|
infrastructure support for developing Java applications. Spring handles the
|
|
infrastructure so you can focus on your application.<!--First text mention should be *Spring Framework* not just *Spring*. I revised next sentence because *plumbing* is idiomatic and --><!--*the domain problem* is an unclear reference. Isn't the point that Spring takes care of *under the covers* so you can focus on app? TR: OK.--></para>
|
|
|
|
<para>Spring enables you to build applications from “plain old Java objects”
|
|
(POJOs) and to apply enterprise services non-invasively to POJOs. This
|
|
capability applies to the Java SE programming model and to full and partial
|
|
Java EE.</para>
|
|
|
|
<para>Examples of how you, as an application developer, can use the Spring
|
|
platform advantage:<!--In each of the examples, clarify what you mean by *the implementer* (identify it, or is it a person?). ALSO in each sentence replace--><!--*dealing with* APIs with what you mean: what does not have to be done in regard to APIs? IMPORTANT, because this discusses advantage--><!--of product. TR: REVISED, PLS REVIEW. I changed *implementer* to *application developer* and put it upfront rather than repeat it.--></para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Make a Java method execute in a database transaction without
|
|
having to deal with transaction APIs.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Make a local Java method a remote procedure without having to deal
|
|
with remote APIs.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Make a local Java method a management operation without having to
|
|
deal with JMX APIs.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Make a local Java method a message handler without having to deal
|
|
with JMS APIs.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<section id="overview-dependency-injection">
|
|
<title>Dependency Injection and Inversion of Control</title>
|
|
|
|
<sidebar id="background-ioc">
|
|
<title>Background</title>
|
|
|
|
<para><quote><emphasis>The question is, what aspect of control are
|
|
[they] inverting?</emphasis></quote> Martin Fowler posed this question
|
|
about Inversion of Control (IoC) on his site in 2004. Fowler suggested
|
|
renaming the principle to make it more self-explanatory and came up with
|
|
<firstterm>Dependency Injection</firstterm>.</para>
|
|
|
|
<para>For insight into IoC and DI, refer to Fowler's article at <ulink
|
|
url="http://martinfowler.com/articles/injection.html">http://martinfowler.com/articles/injection.html</ulink>.</para>
|
|
</sidebar>
|
|
|
|
<para>Java applications -- a loose term that runs the gamut from
|
|
constrained applets to n-tier server-side enterprise applications --
|
|
typically consist of objects that collaborate to form the application
|
|
proper. Thus the objects in an application have
|
|
<emphasis>dependencies</emphasis> on each other.</para>
|
|
|
|
<para>Although the Java platform provides a wealth of application
|
|
development functionality, it lacks the means to organize the basic
|
|
building blocks into a coherent whole, leaving that task to architects and
|
|
developers. True, you can use design patterns such as
|
|
<firstterm>Factory</firstterm>, <firstterm>Abstract Factory</firstterm>,
|
|
<firstterm>Builder</firstterm>, <firstterm>Decorator</firstterm>, and
|
|
<firstterm>Service Locator</firstterm> to compose the various classes and
|
|
object instances that make up an application. However, these patterns are
|
|
simply that: best practices given a name, with a description of what the
|
|
pattern does, where to apply it, the problems it addresses, and so forth.
|
|
Patterns are formalized best practices that <emphasis>you must implement
|
|
yourself</emphasis> in your application.</para>
|
|
|
|
<para>The Spring Framework <emphasis>Inversion of Control</emphasis> (IoC)
|
|
component addresses this concern by providing a formalized means of
|
|
composing disparate components into a fully working application ready for
|
|
use. <!--Preceding sentence sounds like a description of what patterns do (and Spring uses patterns). Distinguish from patterns.-->The
|
|
Spring Framework codifies formalized design patterns as first-class
|
|
objects that you can integrate into your own application(s). <!--Preceding sentence suggests that you already have the application and *then* you integrate design patterns into it. Again, I--><!--don't see a major distinction here from use of patterns (as described in earlier paragraph) and use of IoC component to build apps.
|
|
|
|
TR: This section doesn't read well and I think we should try to rewrite it.-->Numerous
|
|
organizations and institutions use the Spring Framework in this manner to
|
|
engineer robust, <emphasis>maintainable</emphasis> applications.</para>
|
|
</section>
|
|
|
|
<section id="overview-modules">
|
|
<title>Modules</title>
|
|
|
|
<para>The Spring Framework consists of features organized into about 20
|
|
modules. These modules are grouped into Core Container, Data
|
|
Access/Integration, Web, AOP (Aspect Oriented Programming),
|
|
Instrumentation, and Test, as shown in the following diagram.</para>
|
|
|
|
<para><mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata align="left" fileref="images/spring-overview.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<imageobject role="html">
|
|
<imagedata align="center" fileref="images/spring-overview.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<caption><para>Overview of the Spring Framework</para></caption>
|
|
</mediaobject></para>
|
|
|
|
<section>
|
|
<title>Core Container</title>
|
|
|
|
<para>The <link linkend="beans-introduction"><emphasis>Core
|
|
Container</emphasis></link> consists of the Core, Beans, Context, and
|
|
Expression Language modules.</para>
|
|
|
|
<para>The <link linkend="beans-introduction"><emphasis>Core and
|
|
Beans</emphasis></link> modules provide the fundamental parts of the
|
|
framework, including the IoC and Dependency Injection features. The
|
|
<classname>BeanFactory</classname> is a sophisticated implementation of
|
|
the factory pattern. It removes the need for programmatic singletons and
|
|
allows you to decouple the configuration and specification of
|
|
dependencies from your actual program logic.</para>
|
|
|
|
<para>The <link
|
|
linkend="context-introduction"><emphasis>Context</emphasis></link>
|
|
module builds on the solid base provided by the <link
|
|
linkend="beans-introduction"><emphasis>Core and Beans</emphasis></link>
|
|
modules: it is a means to access objects in a framework-style manner
|
|
that is similar to a JNDI registry. The Context module inherits its
|
|
features from the Beans module and adds support for internationalization
|
|
(using, for example, resource bundles), event-propagation,
|
|
resource-loading, and the transparent creation of contexts by, for
|
|
example, a servlet container. The Context module also supports Java EE
|
|
features such as EJB, JMX ,and basic remoting. The
|
|
<classname>ApplicationContext</classname> interface is the focal point
|
|
of the Context module.</para>
|
|
|
|
<para>The <link linkend="expressions"><emphasis>Expression
|
|
Language</emphasis></link> module <!--Provide link as you do with others TR: FIXED.-->provides
|
|
a powerful expression language for querying and manipulating an object
|
|
graph at runtime. It is an extension of the unified expression language
|
|
(unified EL) as specified in the JSP 2.1 specification. The language
|
|
supports setting and getting property values, property assignment,
|
|
method invocation, accessing the context of arrays, collections and
|
|
indexers, logical and arithmetic operators, named variables, and
|
|
retrieval of objects by name from Spring's IoC container. It also
|
|
supports list projection and selection as well as common list
|
|
aggregations.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Data Access/Integration</title>
|
|
|
|
<para>The <emphasis>Data Access/Integration</emphasis> layer consists of
|
|
the JDBC, ORM, OXM, JMS and Transaction modules.</para>
|
|
|
|
<para>The <link linkend="jdbc-introduction">JDBC</link> module provides
|
|
a JDBC-abstraction layer that removes the need to do tedious JDBC coding
|
|
and parsing of database-vendor specific error codes.</para>
|
|
|
|
<para>The <link
|
|
linkend="orm-introduction"><emphasis>ORM</emphasis></link> module
|
|
provides integration layers for popular object-relational mapping APIs,
|
|
including <link linkend="orm-jpa">JPA</link>, <link
|
|
linkend="orm-jdo">JDO</link>, <link
|
|
linkend="orm-hibernate">Hibernate</link>, and <link
|
|
linkend="orm-ibatis">iBatis</link>. Using the ORM package you can use
|
|
all of these O/R-mapping frameworks in combination with all of the other
|
|
features Spring offers, such as the simple declarative transaction
|
|
management feature mentioned previously.</para>
|
|
|
|
<para>The <link linkend="oxm">OXM</link> module provides an abstraction
|
|
layer that supports Object/XML mapping implementations for JAXB, Castor,
|
|
XMLBeans, JiBX and XStream.</para>
|
|
|
|
<para>The Java Messaging Service (<link linkend="jms">JMS</link>) module
|
|
contains features for producing and consuming messages.</para>
|
|
|
|
<para>The <link linkend="transaction">Transaction</link> module supports
|
|
programmatic and declarative transaction management for classes that
|
|
implement special interfaces and for <emphasis>all your POJOs (plain old
|
|
Java objects)</emphasis>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Web</title>
|
|
|
|
<para>The <emphasis>Web</emphasis> layer consists of the Web,
|
|
Web-Servlet, Web-Struts, and Web-Portlet modules.</para>
|
|
|
|
<para>Spring's <emphasis>Web</emphasis> module provides basic
|
|
web-oriented integration features such as multipart file-upload
|
|
functionality and the initialization of the IoC container using servlet
|
|
listeners and a web-oriented application context. It also contains the
|
|
web-related parts of Spring's remoting support.</para>
|
|
|
|
<para>The <emphasis>Web-Servlet</emphasis> module contains Spring's
|
|
model-view-controller (<link
|
|
linkend="mvc-introduction"><emphasis>MVC</emphasis></link>)
|
|
implementation for web applications. Spring's MVC framework provides a
|
|
clean separation between domain model code and web forms, and integrates
|
|
with all the other features of the Spring Framework.<!--MVC allows you to use *all other features*? (Or just all other features in Web layer?) How do you mean? Does this need elaboration?
|
|
It sounds important.--><!--TR: REVISED, PLS REVIEW.--></para>
|
|
|
|
<para>The <emphasis>Web-Struts</emphasis> module contains the support
|
|
classes for integrating a classic Struts web tier within a Spring
|
|
application. Note that this support is now deprecated as of Spring 3.0.
|
|
Consider migrating your application to Struts 2.0 and its Spring
|
|
integration or to a Spring MVC solution.</para>
|
|
|
|
<para>The <emphasis>Web-Portlet</emphasis> module provides the MVC
|
|
implementation to be used in a portlet environment and mirrors the
|
|
functionality of Web-Servlet module.<!--mirrors it in what way?--><!--TR: REVISED, PLS REVIEW. The functionality is mirrored - one for Servlets and the other for Portlets--></para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>AOP and Instrumentation</title>
|
|
|
|
<para>Spring's <link
|
|
linkend="aop-introduction"><emphasis>AOP</emphasis></link> module
|
|
provides an <emphasis>AOP Alliance</emphasis>-compliant aspect-oriented
|
|
programming implementation allowing you to define, for example,
|
|
method-interceptors and pointcuts to cleanly decouple code that
|
|
implements functionality that should be separated. Using source-level
|
|
metadata functionality, you can also incorporate behavioral information
|
|
into your code, in a manner similar to that of .NET attributes.</para>
|
|
|
|
<para>The separate <emphasis>Aspects</emphasis> module provides
|
|
integration with AspectJ.<!--Aspects module not shown in diagram, add it to that. Also, why is this line under AOP and Instrumentation if it's separate?
|
|
|
|
TR: OK. Added to diagram.--></para>
|
|
|
|
<para>The <emphasis>Instrumentation</emphasis> module provides class
|
|
instrumentation support and classloader implementations to be used in
|
|
certain application servers.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Test</title>
|
|
|
|
<para>The <emphasis>Test</emphasis> module supports the testing of
|
|
Spring components with JUnit or TestNG. It provides consistent loading
|
|
of Spring ApplicationContexts and caching of those contexts. It also
|
|
provides mock objects that you can use to test your code in
|
|
isolation.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="overview-usagescenarios">
|
|
<title>Usage scenarios</title>
|
|
|
|
<para>The building blocks described previously make Spring a logical
|
|
choice in many scenarios, from applets to full-fledged enterprise
|
|
applications that use Spring's transaction management functionality and
|
|
web framework integration.</para>
|
|
|
|
<para><mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata align="center" fileref="images/overview-full.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<imageobject role="html">
|
|
<imagedata align="center" fileref="images/overview-full.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<caption><para>Typical full-fledged Spring web
|
|
application</para></caption>
|
|
</mediaobject></para>
|
|
|
|
<para>Spring's <link linkend="transaction-declarative">declarative
|
|
transaction management features</link> make the web application fully
|
|
transactional, just as it would be if you used EJB container-managed
|
|
transactions. All your custom business logic can be implemented with
|
|
simple POJOs and managed by Spring's IoC container. Additional services
|
|
include support for sending email and validation that is independent of
|
|
the web layer, which lets you choose where to execute validation rules.
|
|
Spring's ORM support is integrated with JPA, Hibernate, JDO and iBatis;
|
|
for example, when using Hibernate, you can continue to use your existing
|
|
mapping files and standard Hibernate
|
|
<interfacename>SessionFactory</interfacename> configuration. Form
|
|
controllers seamlessly integrate the web-layer with the domain model,
|
|
removing the need for <classname>ActionForms</classname> or other classes
|
|
that transform HTTP parameters to values for your domain model.</para>
|
|
|
|
<para><mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata align="center"
|
|
fileref="images/overview-thirdparty-web.png" format="PNG" />
|
|
</imageobject>
|
|
|
|
<imageobject role="html">
|
|
<imagedata align="center"
|
|
fileref="images/overview-thirdparty-web.png" format="PNG" />
|
|
</imageobject>
|
|
|
|
<caption><para>Spring middle-tier using a third-party web
|
|
framework</para></caption>
|
|
</mediaobject></para>
|
|
|
|
<para>Sometimes circumstances do not allow you to completely switch to a
|
|
different framework. The Spring Framework does <emphasis>not</emphasis>
|
|
force you to use everything within it; it is not an
|
|
<emphasis>all-or-nothing</emphasis> solution. Existing front-ends built
|
|
with WebWork, Struts, Tapestry, or other UI frameworks can be integrated
|
|
with a Spring-based middle-tier, which allows you to use Spring
|
|
transaction features. You simply need to wire up your business logic using
|
|
an <classname>ApplicationContext</classname> and use a
|
|
<classname>WebApplicationContext </classname>to integrate your web
|
|
layer.</para>
|
|
|
|
<para><mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata align="center" fileref="images/overview-remoting.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<imageobject role="html">
|
|
<imagedata align="center" fileref="images/overview-remoting.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<caption><para>Remoting usage scenario</para></caption>
|
|
</mediaobject></para>
|
|
|
|
<para>When you need to access existing code through web services, you can
|
|
use Spring's <literal>Hessian-</literal>, <literal>Burlap-</literal>,
|
|
<literal>Rmi-</literal> or <classname>JaxRpcProxyFactory</classname>
|
|
classes. Enabling remote access to existing applications is not
|
|
difficult.</para>
|
|
|
|
<para><mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata align="center" fileref="images/overview-ejb.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<imageobject role="html">
|
|
<imagedata align="center" fileref="images/overview-ejb.png"
|
|
format="PNG" />
|
|
</imageobject>
|
|
|
|
<caption><para>EJBs - Wrapping existing POJOs</para></caption>
|
|
</mediaobject></para>
|
|
|
|
<para>The Spring Framework also provides an <link linkend="ejb">access and
|
|
abstraction layer</link> for Enterprise JavaBeans, enabling you to reuse
|
|
your existing POJOs and wrap them in stateless session beans for use in
|
|
scalable, fail-safe web applications that might need declarative
|
|
security.</para>
|
|
|
|
<section id="dependency-management">
|
|
<title>Dependency Management and Naming Conventions</title>
|
|
|
|
<para>Dependency management and dependency injection are different
|
|
things. To get those nice features of Spring into your application (like
|
|
dependency injection) you need to assemble all the libraries needed (jar
|
|
files) and get them onto your classpath at runtime, and possibly at
|
|
compile time. These dependencies are not virtual components that are
|
|
injected, but physical resources in a file system (typically). The
|
|
process of dependency management involves locating those resources,
|
|
storing them and adding them to classpaths. Dependencies can be direct
|
|
(e.g. my application depends on Spring at runtime), or indirect (e.g. my
|
|
application depends on <code>commons-dbcp</code> which depends on
|
|
<code>commons-pool</code>). The indirect dependencies are also known as
|
|
"transitive" and it is those dependencies that are hardest to identify
|
|
and manage.</para>
|
|
|
|
<para>If you are going to use Spring you need to get a copy of the jar
|
|
libraries that comprise the pieces of Spring that you need. To make this
|
|
easier Spring is packaged as a set of modules that separate the
|
|
dependencies as much as possible, so for example if you don't want to
|
|
write a web application you don't need the spring-web modules. To refer
|
|
to Spring library modules in this guide we use a shorthand naming
|
|
convention <code>spring-*</code> or <code>spring-*.jar,</code> where "*"
|
|
represents the short name for the module (e.g. <code>spring-core</code>,
|
|
<code>spring-webmvc</code>, <code>spring-jms</code>, etc.). The actual
|
|
jar file name that you use may be in this form (see below) or it may
|
|
not, and normally it also has a version number in the file name (e.g.
|
|
<code>spring-core-3.0.0.RELEASE.jar</code>).</para>
|
|
|
|
<para>In general, Spring publishes its artifacts to four different
|
|
places:<itemizedlist>
|
|
<listitem>
|
|
<para>On the community download site <ulink
|
|
url="http://www.springsource.org/downloads/community">http://www.springsource.org/downloads/community</ulink>.
|
|
Here you find all the Spring jars bundled together into a zip file
|
|
for easy download. The names of the jars here since version 3.0
|
|
are in the form
|
|
<code>org.springframework.*-<version>.jar</code>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Maven Central, which is the default repository that Maven
|
|
queries, and does not require any special configuration to use.
|
|
Many of the common libraries that Spring depends on also are
|
|
available from Maven Central and a large section of the Spring
|
|
community uses Maven for dependency management, so this is
|
|
convenient for them. The names of the jars here are in the form
|
|
<code>spring-*-<version>.jar</code> and the Maven groupId is
|
|
<code>org.springframework</code>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The Enterprise Bundle Repository (EBR), which is run by
|
|
SpringSource and also hosts all the libraries that integrate with
|
|
Spring. Both Maven and Ivy repositories are available here for all
|
|
Spring jars and their dependencies, plus a large number of other
|
|
common libraries that people use in applications with Spring. Both
|
|
full releases and also milestones and development snapshots are
|
|
deployed here. The names of the jar files are in the same form as
|
|
the community download
|
|
(<code>org.springframework.*-<version>.jar</code>), and the
|
|
dependencies are also in this "long" form, with external libraries
|
|
(not from SpringSource) having the prefix
|
|
<code>com.springsource</code>. See the <ulink security=""
|
|
url="http://www.springsource.com/repository/app/faq">FAQ</ulink>
|
|
for more information.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>In a public Maven repository hosted on Amazon S3 for
|
|
development snapshots and milestone releases (a copy of the final
|
|
releases is also held here). The jar file names are in the same
|
|
form as Maven Central, so this is a useful place to get
|
|
development versions of Spring to use with other libraries depoyed
|
|
in Maven Central.</para>
|
|
</listitem>
|
|
</itemizedlist></para>
|
|
|
|
<para>So the first thing you need to decide is how to manage your
|
|
dependencies: most people use an automated system like Maven or Ivy, but
|
|
you can also do it manually by downloading all the jars yourself. When
|
|
obtaining Spring with Maven or Ivy you have then to decide which place
|
|
you'll get it from. In general, if you care about OSGi, use the EBR,
|
|
since it houses OSGi compatible artifacts for all of Spring's
|
|
dependencies, such as Hibernate and Freemarker. If OSGi does not matter
|
|
to you, either place works, though there are some pros and cons between
|
|
them. In general, pick one place or the other for your project; do not
|
|
mix them. This is particularly important since EBR artifacts necessarily
|
|
use a different naming convention than Maven Central artifacts.</para>
|
|
|
|
<para><table>
|
|
<title>Comparison of Maven Central and SpringSource EBR
|
|
Repositories</title>
|
|
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Feature</entry>
|
|
|
|
<entry>Maven Central</entry>
|
|
|
|
<entry>EBR</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>OSGi Compatible</entry>
|
|
|
|
<entry>Not explicit</entry>
|
|
|
|
<entry>Yes</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Number of Artifacts</entry>
|
|
|
|
<entry>Tens of thousands; all kinds</entry>
|
|
|
|
<entry>Hundreds; those that Spring integrates with</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Consistent Naming Conventions</entry>
|
|
|
|
<entry>No</entry>
|
|
|
|
<entry>Yes</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Naming Convention: GroupId</entry>
|
|
|
|
<entry>Varies. Newer artifacts often use domain name, e.g.
|
|
org.slf4j. Older ones often just use the artifact name, e.g.
|
|
log4j.</entry>
|
|
|
|
<entry>Domain name of origin or main package root, e.g.
|
|
org.springframework</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Naming Convention: ArtifactId</entry>
|
|
|
|
<entry>Varies. Generally the project or module name, using a
|
|
hyphen "-" separator, e.g. spring-core, logj4.</entry>
|
|
|
|
<entry>Bundle Symbolic Name, derived from the main package
|
|
root, e.g. org.springframework.beans. If the jar had to be
|
|
patched to ensure OSGi compliance then com.springsource is
|
|
appended, e.g. com.springsource.org.apache.log4j</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Naming Convention: Version</entry>
|
|
|
|
<entry>Varies. Many new artifacts use m.m.m or m.m.m.X (with
|
|
m=digit, X=text). Older ones use m.m. Some neither. Ordering
|
|
is defined but not often relied on, so not strictly
|
|
reliable.</entry>
|
|
|
|
<entry>OSGi version number m.m.m.X, e.g. 3.0.0.RC3. The text
|
|
qualifier imposes alphabetic ordering on versions with the
|
|
same numeric values.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Publishing</entry>
|
|
|
|
<entry>Usually automatic via rsync or source control updates.
|
|
Project authors can upload individual jars to JIRA.</entry>
|
|
|
|
<entry>Manual (JIRA processed by SpringSource)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Quality Assurance</entry>
|
|
|
|
<entry>By policy. Accuracy is responsibility of
|
|
authors.</entry>
|
|
|
|
<entry>Extensive for OSGi manifest, Maven POM and Ivy
|
|
metadata. QA performed by Spring team.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Hosting</entry>
|
|
|
|
<entry>Contegix. Funded by Sonatype with several
|
|
mirrors.</entry>
|
|
|
|
<entry>S3 funded by SpringSource.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Search Utilities</entry>
|
|
|
|
<entry>Various</entry>
|
|
|
|
<entry><ulink
|
|
url="http://www.springsource.com/repository">http://www.springsource.com/repository</ulink></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Integration with SpringSource Tools</entry>
|
|
|
|
<entry>Integration through STS with Maven dependency
|
|
management</entry>
|
|
|
|
<entry>Extensive integration through STS with Maven, Roo,
|
|
CloudFoundry</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table></para>
|
|
|
|
<section>
|
|
<title>Spring Dependencies and Depending on Spring</title>
|
|
|
|
<para>Although Spring provides integration and support for a huge
|
|
range of enterprise and other external tools, it intentionally keeps
|
|
its mandatory dependencies to an absolute minimum: you shouldn't have
|
|
to locate and download (even automatically) a large number of jar
|
|
libraries in order to use Spring for simple use cases. For basic
|
|
dependency injection there is only one mandatory external dependency,
|
|
and that is for logging (see below for a more detailed description of
|
|
logging options).</para>
|
|
|
|
<para>Next we outline the basic steps needed to configure an
|
|
application that depends on Spring, first with Maven and then with
|
|
Ivy. In all cases, if anything is unclear, refer to the documentation
|
|
of your dependency management system, or look at some sample code -
|
|
Spring itself uses Ivy to manage dependencies when it is building, and
|
|
our samples mostly use Maven.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Maven Dependency Management</title>
|
|
|
|
<para>If you are using Maven for dependency management you don't even
|
|
need to supply the logging dependency explicitly. For example, to
|
|
create an application context and use dependency injection to
|
|
configure an application, your Maven dependencies will look like
|
|
this:</para>
|
|
|
|
<para><programlisting><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>spring-context</artifactId>
|
|
<version>3.0.0.RELEASE</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
</dependencies> </programlisting></para>
|
|
|
|
<para>That's it. Note the scope can be declared as runtime if you
|
|
don't need to compile against Spring APIs, which is typically the case
|
|
for basic dependency injection use cases.</para>
|
|
|
|
<para>We used the Maven Central naming conventions in the example
|
|
above, so that works with Maven Central or the SpringSource S3 Maven
|
|
repository. To use the S3 Maven repository (e.g. for milestones or
|
|
developer snaphots), you need to specify the repository location in
|
|
your Maven configuration. For full releases:</para>
|
|
|
|
<programlisting><repositories>
|
|
<repository>
|
|
<id>com.springsource.repository.maven.release</id>
|
|
<url>http://maven.springframework.org/release/</url>
|
|
<snapshots><enabled>false</enabled></snapshots>
|
|
</repository>
|
|
</repositories></programlisting>
|
|
|
|
<para>For milestones:</para>
|
|
|
|
<programlisting><repositories>
|
|
<repository>
|
|
<id>com.springsource.repository.maven.milestone</id>
|
|
<url>http://maven.springframework.org/milestone/</url>
|
|
<snapshots><enabled>false</enabled></snapshots>
|
|
</repository>
|
|
</repositories></programlisting>
|
|
|
|
<para>And for snapshots:</para>
|
|
|
|
<programlisting><repositories>
|
|
<repository>
|
|
<id>com.springsource.repository.maven.snapshot</id>
|
|
<url>http://maven.springframework.org/snapshot/</url>
|
|
<snapshots><enabled>true</enabled></snapshots>
|
|
</repository>
|
|
</repositories></programlisting>
|
|
|
|
<para>To use the SpringSource EBR you would need to use a different
|
|
naming convention for the dependencies. The names are usually easy to
|
|
guess, e.g. in this case it is:</para>
|
|
|
|
<programlisting><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>org.springframework.context</artifactId>
|
|
<version>3.0.0.RELEASE</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
</dependencies></programlisting>
|
|
|
|
<para>You also need to declare the location of the repository
|
|
explicitly (only the URL is important):</para>
|
|
|
|
<programlisting><repositories>
|
|
<repository>
|
|
<id>com.springsource.repository.bundles.release</id>
|
|
<url>http://repository.springsource.com/maven/bundles/release/</url>
|
|
</repository>
|
|
</repositories></programlisting>
|
|
|
|
<para>If you are managing your dependencies by hand, the URL in the
|
|
repository declaration above is not browseable, but there is a user
|
|
interface at <ulink
|
|
url="http://www.springsource.com/repository">http://www.springsource.com/repository</ulink>
|
|
that can be used to search for and download dependencies. It also has
|
|
handy snippets of Maven and Ivy configuration that you can copy and
|
|
paste if you are using those tools.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Ivy Dependency Management</title>
|
|
|
|
<para>If you prefer to use <ulink
|
|
url="http://ant.apache.org/ivy">Ivy</ulink> to manage dependencies
|
|
then there are similar names and configuration options. </para>
|
|
|
|
<para>To configure Ivy to point to the SpringSource EBR add the
|
|
following resolvers to your
|
|
<filename>ivysettings.xml</filename>:</para>
|
|
|
|
<programlisting><resolvers>
|
|
|
|
<url name="com.springsource.repository.bundles.release">
|
|
|
|
<ivy pattern="http://repository.springsource.com/ivy/bundles/release/
|
|
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
|
<artifact pattern="http://repository.springsource.com/ivy/bundles/release/
|
|
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
|
|
|
</url>
|
|
|
|
<url name="com.springsource.repository.bundles.external">
|
|
|
|
<ivy pattern="http://repository.springsource.com/ivy/bundles/external/
|
|
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
|
<artifact pattern="http://repository.springsource.com/ivy/bundles/external/
|
|
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
|
|
|
</url>
|
|
|
|
</resolvers></programlisting>
|
|
|
|
<para>The XML above is not valid because the lines are too long - if
|
|
you copy-paste then remove the extra line endings in the middle of the
|
|
url patterns.</para>
|
|
|
|
<para>Once Ivy is configured to look in the EBR adding a dependency is
|
|
easy. Simply pull up the details page for the bundle in question in
|
|
the repository browser and you'll find an Ivy snippet ready for you to
|
|
include in your dependencies section. For example (in
|
|
<filename>ivy.xml</filename>): </para>
|
|
|
|
<programlisting><dependency org="org.springframework"
|
|
name="org.springframework.core" rev="3.0.0.RELEASE" conf="compile->runtime"/></programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Logging</title>
|
|
|
|
<para>Logging is a very important dependency for Spring because a) it is
|
|
the only mandatory external dependency, b) everyone likes to see some
|
|
output from the tools they are using, and c) Spring integrates with lots
|
|
of other tools all of which have also made a choice of logging
|
|
dependency. One of the goals of an application developer is often to
|
|
have unified logging configured in a central place for the whole
|
|
application, including all external components. This is more difficult
|
|
than it might have been since there are so many choices of logging
|
|
framework.</para>
|
|
|
|
<para>The mandatory logging dependency in Spring is the Jakarta Commons
|
|
Logging API (JCL). We compile against JCL and we also make JCL
|
|
<classname>Log</classname> objects visible for classes that extend the
|
|
Spring Framework. It's important to users that all versions of Spring
|
|
use the same logging library: migration is easy because backwards
|
|
compatibility is preserved even with applications that extend Spring.
|
|
The way we do this is to make one of the modules in Spring depend
|
|
explicitly on <code>commons-logging</code> (the canonical implementation
|
|
of JCL), and then make all the other modules depend on that at compile
|
|
time. If you are using Maven for example, and wondering where you picked
|
|
up the dependency on <code>commons-logging</code>, then it is from
|
|
Spring and specifically from the central module called
|
|
<code>spring-core</code>.</para>
|
|
|
|
<para>The nice thing about <code>commons-logging</code> is that you
|
|
don't need anything else to make your application work. It has a runtime
|
|
discovery algorithm that looks for other logging frameworks in well
|
|
known places on the classpath and uses one that it thinks is appropriate
|
|
(or you can tell it which one if you need to). If nothing else is
|
|
available you get pretty nice looking logs just from the JDK
|
|
(java.util.logging or JUL for short). You should find that your Spring
|
|
application works and logs happily to the console out of the box in most
|
|
situations, and that's important.</para>
|
|
|
|
<section>
|
|
<title>Not Using Commons Logging</title>
|
|
|
|
<para>Unfortunately, the runtime discovery algorithm in
|
|
<code>commons-logging</code>, while convenient for the end-user, is
|
|
problematic. If we could turn back the clock and start Spring now
|
|
as a new project it would use a different logging dependency. The
|
|
first choice would probably be the Simple Logging Facade for Java (<ulink
|
|
url="http://www.slf4j.org">SLF4J</ulink>), which is also used by a lot
|
|
of other tools that people use with Spring inside their
|
|
applications.</para>
|
|
|
|
<para>Switching off <code>commons-logging</code> is easy: just make
|
|
sure it isn't on the classpath at runtime. In Maven terms you exclude
|
|
the dependency, and because of the way that the Spring dependencies
|
|
are declared, you only have to do that once.</para>
|
|
|
|
<programlisting><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>spring-context</artifactId>
|
|
<version>3.0.0.RELEASE</version>
|
|
<scope>runtime</scope>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>commons-logging</groupId>
|
|
<artifactId>commons-logging</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
</dependencies> </programlisting>
|
|
|
|
<para>Now this application is probably broken because there is no
|
|
implementation of the JCL API on the classpath, so to fix it a new one
|
|
has to be provided. In the next section we show you how to provide an
|
|
alternative implementation of JCL using SLF4J as an example.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Using SLF4J</title>
|
|
</section>
|
|
|
|
<para>SLF4J is a cleaner dependency and more efficient at runtime than
|
|
<code>commons-logging</code> because it uses compile-time bindings
|
|
instead of runtime discovery of the other logging frameworks it
|
|
integrates. This also means that you have to be more explicit about what
|
|
you want to happen at runtime, and declare it or configure it
|
|
accordingly. SLF4J provides bindings to many common logging frameworks,
|
|
so you can usually choose one that you already use, and bind to that for
|
|
configuration and management.</para>
|
|
|
|
<para>SLF4J provides bindings to many common logging frameworks,
|
|
including JCL, and it also does the reverse: bridges between other
|
|
logging frameworks and itself. So to use SLF4J with Spring you need to
|
|
replace the <code>commons-logging</code> dependency with the SLF4J-JCL
|
|
bridge. Once you have done that then logging calls from within Spring
|
|
will be translated into logging calls to the SLF4J API, so if other
|
|
libraries in your application use that API, then you have a single place
|
|
to configure and manage logging.</para>
|
|
|
|
<para>A common choice might be to bridge Spring to SLF4J, and then
|
|
provide explicit binding from SLF4J to Log4J. You need to supply 4
|
|
dependencies (and exclude the existing <code>commons-logging</code>):
|
|
the bridge, the SLF4J API, the binding to Log4J, and the Log4J
|
|
implementation itself. In Maven you would do that like this</para>
|
|
|
|
<programlisting><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>spring-context</artifactId>
|
|
<version>3.0.0.RELEASE</version>
|
|
<scope>runtime</scope>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>commons-logging</groupId>
|
|
<artifactId>commons-logging</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.slf4j</groupId>
|
|
<artifactId>jcl-over-slf4j</artifactId>
|
|
<version>1.5.8</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.slf4j</groupId>
|
|
<artifactId>slf4j-api</artifactId>
|
|
<version>1.5.8</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.slf4j</groupId>
|
|
<artifactId>slf4j-log4j12</artifactId>
|
|
<version>1.5.8</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>log4j</groupId>
|
|
<artifactId>log4j</artifactId>
|
|
<version>1.2.14</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
</dependencies> </programlisting>
|
|
|
|
<para>That might seem like a lot of dependencies just to get some
|
|
logging. Well it is, but it <emphasis>is</emphasis> optional, and it
|
|
should behave better than the vanilla <code>commons-logging</code> with
|
|
respect to classloader issues, notably if you are in a strict container
|
|
like an OSGi platform. Allegedly there is also a performance benefit
|
|
because the bindings are at compile-time not runtime.</para>
|
|
|
|
<para>A more common choice amongst SLF4J users, which uses fewer steps
|
|
and generates fewer dependencies, is to bind directly to <ulink type=""
|
|
url="http://logback.qos.ch">Logback</ulink>. This removes the extra
|
|
binding step because Logback implements SLF4J directly, so you only need
|
|
to depend on two libaries not four (<code>jcl-over-slf4j</code> and
|
|
<code>logback</code>). If you do that you might also need to exlude the
|
|
slf4j-api dependency from other external dependencies (not Spring),
|
|
because you only want one version of that API on the classpath.</para>
|
|
|
|
<section>
|
|
<title>Using Log4J</title>
|
|
|
|
<para>Many people use <ulink
|
|
url="http://logging.apache.org/log4j">Log4j</ulink> as a logging
|
|
framework for configuration and management purposes. It's efficient
|
|
and well-established, and in fact it's what we use at runtime when we
|
|
build and test Spring. Spring also provides some utilities for
|
|
configuring and initializing Log4j, so it has an optional compile-time
|
|
dependency on Log4j in some modules.</para>
|
|
|
|
<para>To make Log4j work with the default JCL dependency
|
|
(<code>commons-logging</code>) all you need to do is put Log4j on the
|
|
classpath, and provide it with a configuration file
|
|
(<code>log4j.properties</code> or <code>log4j.xml</code> in the root
|
|
of the classpath). So for Maven users this is your dependency
|
|
declaration:</para>
|
|
|
|
<programlisting><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>spring-context</artifactId>
|
|
<version>3.0.0.RELEASE</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>log4j</groupId>
|
|
<artifactId>log4j</artifactId>
|
|
<version>1.2.14</version>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
</dependencies> </programlisting>
|
|
|
|
<para>And here's a sample log4j.properties for logging to the
|
|
console:</para>
|
|
|
|
<programlisting>log4j.rootCategory=INFO, stdout
|
|
|
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
|
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
|
|
|
|
log4j.category.org.springframework.beans.factory=DEBUG</programlisting>
|
|
|
|
<section>
|
|
<title>Runtime Containers with Native JCL</title>
|
|
|
|
<para>Many people run their Spring applications in a container that
|
|
itself provides an implementation of JCL. IBM Websphere Application
|
|
Server (WAS) is the archetype. This often causes problems, and
|
|
unfortunately there is no silver bullet solution; simply excluding
|
|
<code>commons-logging</code> from your application is not enough in
|
|
most situations.</para>
|
|
|
|
<para>To be clear about this: the problems reported are usually not
|
|
with JCL per se, or even with <code>commons-logging</code>: rather
|
|
they are to do with binding <code>commons-logging</code> to another
|
|
framework (often Log4J). This can fail because
|
|
<code>commons-logging</code> changed the way they do the runtime
|
|
discovery in between the older versions (1.0) found in some
|
|
containers and the modern versions that most people use now (1.1).
|
|
Spring does not use any unusual parts of the JCL API, so nothing
|
|
breaks there, but as soon as Spring or your application tries to do
|
|
any logging you can find that the bindings to Log4J are not
|
|
working.</para>
|
|
|
|
<para>In such cases with WAS the easiest thing to do is to invert
|
|
the class loader hierarchy (IBM calls it "parent last") so that the
|
|
application controls the JCL dependency, not the container. That
|
|
option isn't always open, but there are plenty of other suggestions
|
|
in the public domain for alternative approaches, and your mileage
|
|
may vary depending on the exact version and feature set of the
|
|
container.</para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
</chapter>
|