You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
962 lines
45 KiB
962 lines
45 KiB
<?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>
|
|
|