Move reference docs => src/reference
This change eliminates the spring-framework-reference subproject, moving these sources into the root project's own src directory. This makes sense because the reference docs span all submodules, and also because api Javadoc is created at the root project level as well. This means that both api and reference documentation output will now reside in the root project's 'build' directory. This is more consistent and easy to discover.
This commit is contained in:
962
src/reference/docbook/overview.xml
Normal file
962
src/reference/docbook/overview.xml
Normal file
@@ -0,0 +1,962 @@
|
||||
<?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>
|
||||
Reference in New Issue
Block a user