Migrate reference guide to well-formed docbook XML

Convert all docbook XML files to well-formed docbook 5 syntax:
 - Include xsi:schemaLocation element for tools support
 - Convert all id elements to xml:id
 - Convert all ulink elements to link
 - Simplify <lineannotation> mark-up
 - Fix misplaced </section> tags
 - Fix <interface> tags to <interfacename>
 - Cleanup trailing whitespace and tabs

Issue: SPR-10032
This commit is contained in:
Phillip Webb
2012-11-25 18:04:46 -08:00
parent 89b443c198
commit c37080d49d
50 changed files with 5765 additions and 5383 deletions

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="aop-api"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="aop-api">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Spring AOP APIs</title>
<section id="aop-api-introduction">
<section xml:id="aop-api-introduction">
<title>Introduction</title>
<para>The previous chapter described the Spring 2.0 and later version's
@@ -19,13 +23,13 @@
described in this chapter is fully supported in Spring 3.0.</para>
</section>
<section id="aop-api-pointcuts">
<section xml:id="aop-api-pointcuts">
<title>Pointcut API in Spring</title>
<para>Let's look at how Spring handles the crucial pointcut
concept.</para>
<section id="aop-api-concepts">
<section xml:id="aop-api-concepts">
<title>Concepts</title>
<para>Spring's pointcut model enables pointcut reuse independent of
@@ -93,7 +97,7 @@
</tip>
</section>
<section id="aop-api-pointcut-ops">
<section xml:id="aop-api-pointcut-ops">
<title>Operations on pointcuts</title>
<para>Spring supports operations on pointcuts: notably,
@@ -123,7 +127,7 @@
</itemizedlist>
</section>
<section id="aop-api-pointcuts-aspectj">
<section xml:id="aop-api-pointcuts-aspectj">
<title>AspectJ expression pointcuts</title>
<para>Since 2.0, the most important type of pointcut used by Spring is
@@ -135,14 +139,14 @@
pointcut primitives.</para>
</section>
<section id="aop-api-pointcuts-impls">
<section xml:id="aop-api-pointcuts-impls">
<title>Convenience pointcut implementations</title>
<para>Spring provides several convenient pointcut implementations. Some
can be used out of the box; others are intended to be subclassed in
application-specific pointcuts.</para>
<section id="aop-api-pointcuts-static">
<section xml:id="aop-api-pointcuts-static">
<title>Static pointcuts</title>
<para>Static pointcuts are based on method and target class, and
@@ -155,7 +159,7 @@
<para>Let's consider some static pointcut implementations included
with Spring.</para>
<section id="aop-api-pointcuts-regex">
<section xml:id="aop-api-pointcuts-regex">
<title>Regular expression pointcuts</title>
<para>One obvious way to specify static pointcuts is regular
@@ -172,7 +176,7 @@
<para>The usage is shown below:</para>
<para><programlisting language="xml">&lt;bean id="settersAndAbsquatulatePointcut"
<para><programlisting language="xml">&lt;bean id="settersAndAbsquatulatePointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointcut"&gt;
&lt;property name="patterns"&gt;
&lt;list&gt;
@@ -191,7 +195,7 @@
the one bean encapsulates both pointcut and advice, as shown
below:</para>
<para><programlisting language="xml">&lt;bean id="settersAndAbsquatulateAdvisor"
<para><programlisting language="xml">&lt;bean id="settersAndAbsquatulateAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt;
&lt;property name="advice"&gt;
&lt;ref local="beanNameOfAopAllianceInterceptor"/&gt;
@@ -208,7 +212,7 @@
with any Advice type.</para>
</section>
<section id="aop-api-pointcuts-attribute-driven">
<section xml:id="aop-api-pointcuts-attribute-driven">
<title>Attribute-driven pointcuts</title>
<para>An important type of static pointcut is a
@@ -217,7 +221,7 @@
</section>
</section>
<section id="aop-api-pointcuts-dynamic">
<section xml:id="aop-api-pointcuts-dynamic">
<title>Dynamic pointcuts</title>
<para>Dynamic pointcuts are costlier to evaluate than static
@@ -229,7 +233,7 @@
<para>The main example is the <literal>control flow</literal>
pointcut.</para>
<section id="aop-api-pointcuts-cflow">
<section xml:id="aop-api-pointcuts-cflow">
<title>Control flow pointcuts</title>
<para>Spring control flow pointcuts are conceptually similar to
@@ -252,7 +256,7 @@
</section>
</section>
<section id="aop-api-pointcuts-superclasses">
<section xml:id="aop-api-pointcuts-superclasses">
<title>Pointcut superclasses</title>
<para>Spring provides useful pointcut superclasses to help you to
@@ -274,7 +278,7 @@
RC2 and above.</para>
</section>
<section id="aop-api-pointcuts-custom">
<section xml:id="aop-api-pointcuts-custom">
<title>Custom pointcuts</title>
<para>Because pointcuts in Spring AOP are Java classes, rather than
@@ -291,12 +295,12 @@
</section>
</section>
<section id="aop-api-advice">
<section xml:id="aop-api-advice">
<title>Advice API in Spring</title>
<para>Let's now look at how Spring AOP handles advice.</para>
<section id="aop-api-advice-lifecycle">
<section xml:id="aop-api-advice-lifecycle">
<title>Advice lifecycles</title>
<para>Each advice is a Spring bean. An advice instance can be shared
@@ -317,14 +321,14 @@
the same AOP proxy.</para>
</section>
<section id="aop-api-advice-types">
<section xml:id="aop-api-advice-types">
<title>Advice types in Spring</title>
<para>Spring provides several advice types out of the box, and is
extensible to support arbitrary advice types. Let us look at the basic
concepts and standard advice types.</para>
<section id="aop-api-advice-around">
<section xml:id="aop-api-advice-around">
<title>Interception around advice</title>
<para>The most fundamental advice type in Spring is
@@ -335,7 +339,7 @@
around advice should implement the following interface:</para>
<programlisting language="java">public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}</programlisting>
@@ -379,7 +383,7 @@
</note>
</section>
<section id="aop-api-advice-before">
<section xml:id="aop-api-advice-before">
<title>Before advice</title>
<para>A simpler advice type is a <emphasis role="bold">before
@@ -422,8 +426,8 @@
++count;
}
public int getCount() {
return count;
public int getCount() {
return count;
}
}</programlisting>
@@ -432,7 +436,7 @@
</tip>
</section>
<section id="aop-api-advice-throws">
<section xml:id="aop-api-advice-throws">
<title>Throws advice</title>
<para><emphasis role="bold">Throws advice</emphasis> is invoked after
@@ -484,7 +488,7 @@
public void afterThrowing(RemoteException ex) throws Throwable {
// Do something with remote exception
}
public void afterThrowing(Method m, Object[] args, Object target, ServletException ex) {
// Do something with all arguments
}
@@ -506,7 +510,7 @@
</tip>
</section>
<section id="aop-api-advice-after-returning">
<section xml:id="aop-api-advice-after-returning">
<title>After Returning advice</title>
<para>An after returning advice in Spring must implement the
@@ -515,7 +519,7 @@
<programlisting language="java">public interface AfterReturningAdvice extends Advice {
void afterReturning(Object returnValue, Method m, Object[] args, Object target)
void afterReturning(Object returnValue, Method m, Object[] args, Object target)
throws Throwable;
}</programlisting>
@@ -549,30 +553,30 @@
</tip>
</section>
<section id="aop-api-advice-introduction">
<section xml:id="aop-api-advice-introduction">
<title>Introduction advice</title>
<para>Spring treats introduction advice as a special kind of
interception advice.</para>
<para>Introduction requires an <literal>IntroductionAdvisor</literal>,
and an <literal>IntroductionInterceptor</literal>, implementing the
following interface:</para>
<programlisting language="java">public interface IntroductionInterceptor extends MethodInterceptor {
boolean implementsInterface(Class intf);
}</programlisting>
<para>The <literal>invoke() </literal>method inherited from the AOP
Alliance <literal>MethodInterceptor</literal> interface must implement
@@ -581,53 +585,47 @@
the method call - it cannot invoke
<literal>proceed()</literal>.</para>
<para>Introduction advice cannot be used with any pointcut, as it
applies only at class, rather than method, level. You can only use
introduction advice with the <literal>IntroductionAdvisor</literal>,
which has the following methods:</para>
<programlisting language="java">public interface IntroductionAdvisor extends Advisor, IntroductionInfo {
ClassFilter getClassFilter();
ClassFilter getClassFilter();
void validateInterfaces() throws IllegalArgumentException;
void validateInterfaces() throws IllegalArgumentException;
}
public interface IntroductionInfo {
Class[] getInterfaces();
Class[] getInterfaces();
}</programlisting>
<para>There is no <interfacename>MethodMatcher</interfacename>, and
hence no <interfacename>Pointcut</interfacename>, associated with
introduction advice. Only class filtering is logical.</para>
<para>The <literal>getInterfaces()</literal> method returns the
interfaces introduced by this advisor.</para>
The
<literal>validateInterfaces()</literal>
method is used internally to see whether or not the introduced interfaces can be implemented by the configured
<literal>IntroductionInterceptor</literal>
.
<para>The <literal>validateInterfaces()</literal> method is used internally to
see whether or not the introduced interfaces can be implemented by the configured
<literal>IntroductionInterceptor</literal>.</para>
<para>Let's look at a simple example from the Spring test suite. Let's
suppose we want to introduce the following interface to one or more
objects:</para>
<para>
<programlisting language="java">public interface Lockable {
@@ -637,7 +635,7 @@ public interface IntroductionInfo {
}</programlisting>
</para>
<para>This illustrates a <emphasis role="bold">mixin</emphasis>. We
want to be able to cast advised objects to Lockable, whatever their
@@ -647,7 +645,7 @@ public interface IntroductionInfo {
provides the ability to make objects immutable, without them having
any knowledge of it: a good example of AOP.</para>
<para>Firstly, we'll need an
<literal>IntroductionInterceptor</literal> that does the heavy
@@ -658,7 +656,7 @@ public interface IntroductionInfo {
<literal>DelegatingIntroductionInterceptor</literal> is best for most
cases.</para>
<para>The <literal>DelegatingIntroductionInterceptor</literal> is
designed to delegate an introduction to an actual implementation of
@@ -682,7 +680,7 @@ public interface IntroductionInfo {
will conceal any implementation of the same interface by the
target.</para>
<para>Thus LockMixin subclasses
<literal>DelegatingIntroductionInterceptor</literal> and implements
@@ -690,16 +688,16 @@ public interface IntroductionInfo {
can be supported for introduction, so we don't need to specify that.
We could introduce any number of interfaces in this way.</para>
<para>Note the use of the <literal>locked</literal> instance variable.
This effectively adds additional state to that held in the target
object.</para>
<para>
<programlisting language="java">public class LockMixin extends DelegatingIntroductionInterceptor
<programlisting language="java">public class LockMixin extends DelegatingIntroductionInterceptor
implements Lockable {
private boolean locked;
@@ -725,7 +723,7 @@ public interface IntroductionInfo {
}</programlisting>
</para>
<para>Often it isn't necessary to override the <literal>invoke()
</literal>method: the
@@ -735,7 +733,7 @@ public interface IntroductionInfo {
present case, we need to add a check: no setter method can be invoked
if in locked mode.</para>
<para>The introduction advisor required is simple. All it needs to do
is hold a distinct <literal>LockMixin</literal> instance, and specify
@@ -746,7 +744,7 @@ public interface IntroductionInfo {
<literal>LockMixin</literal>, so we simply create it using
<literal>new</literal>.</para>
<para>
<programlisting language="java">public class LockMixinAdvisor extends DefaultIntroductionAdvisor {
@@ -757,7 +755,7 @@ public interface IntroductionInfo {
}</programlisting>
</para>
<para>We can apply this advisor very simply: it requires no
configuration. (However, it <emphasis>is</emphasis> necessary: It's
@@ -768,7 +766,7 @@ public interface IntroductionInfo {
hence <literal>LockMixin</literal>, for each advised object. The
advisor comprises part of the advised object's state.</para>
<para>We can apply this advisor programmatically, using the
<literal>Advised.addAdvisor() </literal>method, or (the recommended
@@ -776,12 +774,12 @@ public interface IntroductionInfo {
choices discussed below, including "auto proxy creators," correctly
handle introductions and stateful mixins.</para>
</section>
</section>
</section>
<section id="aop-api-advisor">
<section xml:id="aop-api-advisor">
<title>Advisor API in Spring</title>
<para>In Spring, an Advisor is an aspect that contains just a single
@@ -800,7 +798,7 @@ public interface IntroductionInfo {
automatically create the necessary interceptor chain.</para>
</section>
<section id="aop-pfb">
<section xml:id="aop-pfb">
<title>Using the ProxyFactoryBean to create AOP proxies</title>
<para>If you're using the Spring IoC container (an ApplicationContext or
@@ -820,7 +818,7 @@ public interface IntroductionInfo {
and their ordering. However, there are simpler options that are preferable
if you don't need such control.</para>
<section id="aop-pfb-1">
<section xml:id="aop-pfb-1">
<title>Basics</title>
<para>The <literal>ProxyFactoryBean</literal>, like other Spring
@@ -843,7 +841,7 @@ public interface IntroductionInfo {
pluggability provided by Dependency Injection.</para>
</section>
<section id="aop-pfb-2">
<section xml:id="aop-pfb-2">
<title>JavaBean properties</title>
<para>In common with most <interfacename>FactoryBean</interfacename>
@@ -949,7 +947,7 @@ public interface IntroductionInfo {
</itemizedlist>
</section>
<section id="aop-pfb-proxy-types">
<section xml:id="aop-pfb-proxy-types">
<title>JDK- and CGLIB-based proxies</title>
<para>This section serves as the definitive documentation on how the
@@ -1018,7 +1016,7 @@ public interface IntroductionInfo {
significantly less work, and less prone to typos.</para>
</section>
<section id="aop-api-proxying-intf">
<section xml:id="aop-api-proxying-intf">
<title>Proxying interfaces</title>
<para>Let's look at a simple example of
@@ -1054,7 +1052,7 @@ public interface IntroductionInfo {
&lt;bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"&gt;
&lt;/bean&gt;
&lt;bean id="person"
&lt;bean id="person"
class="org.springframework.aop.framework.ProxyFactoryBean"&gt;
&lt;property name="proxyInterfaces" value="com.mycompany.Person"/&gt;
@@ -1141,7 +1139,7 @@ public interface IntroductionInfo {
example, in certain test scenarios.</para>
</section>
<section id="aop-api-proxying-class">
<section xml:id="aop-api-proxying-class">
<title>Proxying classes</title>
<para>What if you need to proxy a class, rather than one or more
@@ -1190,7 +1188,7 @@ public interface IntroductionInfo {
decisive consideration in this case.</para>
</section>
<section id="aop-global-advisors">
<section xml:id="aop-global-advisors">
<title>Using 'global' advisors</title>
<para>By appending an asterisk to an interceptor name, all advisors with
@@ -1212,7 +1210,7 @@ public interface IntroductionInfo {
</section>
</section>
<section id="aop-concise-proxy">
<section xml:id="aop-concise-proxy">
<title>Concise proxy definitions</title>
<para>Especially when defining transactional proxies, you may end up with
@@ -1275,7 +1273,7 @@ public interface IntroductionInfo {
it.</para>
</section>
<section id="aop-prog">
<section xml:id="aop-prog">
<title>Creating AOP proxies programmatically with the ProxyFactory</title>
<para>It's easy to create AOP proxies programmatically using Spring. This
@@ -1312,7 +1310,7 @@ MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();</programlisti
</tip>
</section>
<section id="aop-api-advised">
<section xml:id="aop-api-advised">
<title>Manipulating advised objects</title>
<para>However you create AOP proxies, you can manipulate them using the
@@ -1324,7 +1322,7 @@ MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();</programlisti
void addAdvice(Advice advice) throws AopConfigException;
void addAdvice(int pos, Advice advice)
void addAdvice(int pos, Advice advice)
throws AopConfigException;
void addAdvisor(Advisor advisor) throws AopConfigException;
@@ -1406,7 +1404,7 @@ assertEquals("Added two advisors",
advice modification is known not to be required.</para>
</section>
<section id="aop-autoproxy">
<section xml:id="aop-autoproxy">
<title>Using the "autoproxy" facility</title>
<para>So far we've considered explicit creation of AOP proxies using a
@@ -1437,13 +1435,13 @@ assertEquals("Added two advisors",
</listitem>
</itemizedlist>
<section id="aop-autoproxy-choices">
<section xml:id="aop-autoproxy-choices">
<title>Autoproxy bean definitions</title>
<para>The <literal>org.springframework.aop.framework.autoproxy</literal>
package provides the following standard autoproxy creators.</para>
<section id="aop-api-autoproxy">
<section xml:id="aop-api-autoproxy">
<title>BeanNameAutoProxyCreator</title>
<para>The <literal>BeanNameAutoProxyCreator</literal> class is a
@@ -1480,7 +1478,7 @@ assertEquals("Added two advisors",
differently to different beans.</para>
</section>
<section id="aop-api-autoproxy-default">
<section xml:id="aop-api-autoproxy-default">
<title>DefaultAdvisorAutoProxyCreator</title>
<para>A more general and extremely powerful auto proxy creator is
@@ -1559,7 +1557,7 @@ assertEquals("Added two advisors",
configurable order value; the default setting is unordered.</para>
</section>
<section id="aop-api-autoproxy-abstract">
<section xml:id="aop-api-autoproxy-abstract">
<title>AbstractAdvisorAutoProxyCreator</title>
<para>This is the superclass of DefaultAdvisorAutoProxyCreator. You
@@ -1570,7 +1568,7 @@ assertEquals("Added two advisors",
</section>
</section>
<section id="aop-autoproxy-metadata">
<section xml:id="aop-autoproxy-metadata">
<title>Using metadata-driven auto-proxying</title>
<para>A particularly important type of autoproxying is driven by
@@ -1660,7 +1658,7 @@ assertEquals("Added two advisors",
be specific to the application's transaction requirements (typically
JTA, as in this example, or Hibernate, JDO or JDBC):</para>
<programlisting language="xml">&lt;bean id="transactionManager"
<programlisting language="xml">&lt;bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/&gt;</programlisting>
<tip>
@@ -1718,7 +1716,7 @@ assertEquals("Added two advisors",
</section>
</section>
<section id="aop-targetsource">
<section xml:id="aop-targetsource">
<title>Using TargetSources</title>
<para>Spring offers the concept of a <emphasis>TargetSource</emphasis>,
@@ -1747,7 +1745,7 @@ assertEquals("Added two advisors",
Spring to create a new target instance when required.</para>
</tip>
<section id="aop-ts-swap">
<section xml:id="aop-ts-swap">
<title>Hot swappable target sources</title>
<para>The
@@ -1761,7 +1759,7 @@ assertEquals("Added two advisors",
<para>You can change the target via the <literal>swap()</literal> method
on HotSwappableTargetSource as follows:</para>
<para><programlisting language="java">HotSwappableTargetSource swapper =
<para><programlisting language="java">HotSwappableTargetSource swapper =
(HotSwappableTargetSource) beanFactory.getBean("swapper");
Object oldTarget = swapper.swap(newTarget);</programlisting></para>
@@ -1788,7 +1786,7 @@ Object oldTarget = swapper.swap(newTarget);</programlisting></para>
with arbitrary advice.</para>
</section>
<section id="aop-ts-pool">
<section xml:id="aop-ts-pool">
<title>Pooling target sources</title>
<para>Using a pooling target source provides a similar programming model
@@ -1809,7 +1807,7 @@ Object oldTarget = swapper.swap(newTarget);</programlisting></para>
<para>Sample configuration is shown below:</para>
<para><programlisting language="xml">&lt;bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject"
<para><programlisting language="xml">&lt;bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject"
scope="prototype"&gt;
... properties omitted
&lt;/bean&gt;
@@ -1872,7 +1870,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());</programlisting>
set the TargetSources used by any autoproxy creator.</para>
</section>
<section id="aop-ts-prototype">
<section xml:id="aop-ts-prototype">
<title>Prototype target sources</title>
<para>Setting up a "prototype" target source is similar to a pooling
@@ -1896,7 +1894,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());</programlisting>
must be a prototype bean definition.</para>
</section>
<section id="aop-ts-threadlocal">
<section xml:id="aop-ts-threadlocal">
<title><classname>ThreadLocal</classname> target sources</title>
<para><classname>ThreadLocal</classname> target sources are useful if
@@ -1928,7 +1926,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());</programlisting>
</section>
</section>
<section id="aop-extensibility">
<section xml:id="aop-extensibility">
<title>Defining new <interfacename>Advice</interfacename> types</title>
<para>Spring AOP is designed to be extensible. While the interception
@@ -1949,7 +1947,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());</programlisting>
Javadocs for further information.</para>
</section>
<section id="aop-api-resources">
<section xml:id="aop-api-resources">
<title>Further resources</title>
<para>Please refer to the Spring sample applications for further examples

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-annotation-config"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-annotation-config">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Annotation-based container configuration</title>
<sidebar>
@@ -25,8 +29,8 @@
linkend="beans-java">JavaConfig</link> option, Spring allows annotations
to be used in a non-invasive way, without touching the target components
source code and that in terms of tooling, all configuration styles are
supported by the <ulink url="http://www.springsource.com/products/sts"
>SpringSource Tool Suite</ulink>.</para>
supported by the <link xl:href="http://www.springsource.com/products/sts"
>SpringSource Tool Suite</link>.</para>
</sidebar>
<para>An alternative to XML setups is provided by annotation-based
@@ -51,10 +55,10 @@
JSR-330 (Dependency Injection for Java) annotations contained in the
javax.inject package such as <classname>@Inject</classname> and
<literal> @Named</literal>. Details about those annotations can be found in the <link linkend="beans-standard-annotations"
>relevant section</link>. <note> Annotation injection is performed
>relevant section</link>. <note><para>Annotation injection is performed
<emphasis>before</emphasis> XML injection, thus the latter configuration
will override the former for properties wired through both approaches.
</note> As always, you can register them as individual bean definitions, but
</para></note> As always, you can register them as individual bean definitions, but
they can also be implicitly registered by including the following tag in an
XML-based Spring configuration (notice the inclusion of the
<literal>context</literal> namespace):</para>
@@ -72,16 +76,16 @@
&lt;/beans&gt;</programlisting>
<para>(The implicitly registered post-processors include <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html"
><classname>AutowiredAnnotationBeanPostProcessor</classname></ulink>, <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.html"
><classname>CommonAnnotationBeanPostProcessor</classname></ulink>, <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html"
><classname>PersistenceAnnotationBeanPostProcessor</classname></ulink>, as
well as the aforementioned <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.html"
><classname>RequiredAnnotationBeanPostProcessor</classname></ulink>.)</para>
<para>(The implicitly registered post-processors include <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html"
><classname>AutowiredAnnotationBeanPostProcessor</classname></link>, <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.html"
><classname>CommonAnnotationBeanPostProcessor</classname></link>, <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html"
><classname>PersistenceAnnotationBeanPostProcessor</classname></link>, as
well as the aforementioned <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.html"
><classname>RequiredAnnotationBeanPostProcessor</classname></link>.)</para>
<note>
<para><literal>&lt;context:annotation-config/&gt;</literal> only looks for
@@ -95,7 +99,7 @@
information.</para>
</note>
<section id="beans-required-annotation">
<section xml:id="beans-required-annotation">
<title><interfacename>@Required</interfacename></title>
<para>The <interfacename>@Required</interfacename> annotation applies to
@@ -124,14 +128,14 @@
and values even when you use the class outside of a container.</para>
</section>
<section id="beans-autowired-annotation">
<section xml:id="beans-autowired-annotation">
<title><interfacename>@Autowired</interfacename></title>
<para>As expected, you can apply the
<interfacename>@Autowired</interfacename> annotation to "traditional"
setter methods:</para>
<programlisting language="java">public class SimpleMovieLister {
@@ -145,13 +149,13 @@
<lineannotation>// ...</lineannotation>
}</programlisting>
<note>
<note>
<para>JSR 330's @Inject annotation can be used in place of Spring's
<interfacename>@Autowired</interfacename> annotation in the examples below. See <link linkend="beans-standard-annotations"
>here</link> for more details</para>
</note>
<para>You can also apply the annotation to methods with arbitrary names
and/or multiple arguments:</para>
@@ -310,7 +314,7 @@
</note>
</section>
<section id="beans-autowired-annotation-qualifiers">
<section xml:id="beans-autowired-annotation-qualifiers">
<title>Fine-tuning annotation-based autowiring with qualifiers</title>
<para>Because autowiring by type may lead to multiple candidates, it is
@@ -635,12 +639,12 @@ public @interface MovieQualifier {
&lt;/beans&gt;</programlisting>
</section>
<section id="beans-custom-autowire-configurer">
<section xml:id="beans-custom-autowire-configurer">
<title><classname>CustomAutowireConfigurer</classname></title>
<para>The <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.html"
><classname>CustomAutowireConfigurer</classname></ulink> is a
<para>The <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.html"
><classname>CustomAutowireConfigurer</classname></link> is a
<interfacename>BeanFactoryPostProcessor</interfacename> that enables you
to register your own custom qualifier annotation types even if they are
not annotated with Spring's <interfacename>@Qualifier</interfacename>
@@ -675,7 +679,7 @@ public @interface MovieQualifier {
will be selected.</para>
</section>
<section id="beans-resource-annotation">
<section xml:id="beans-resource-annotation">
<title><interfacename>@Resource</interfacename></title>
<para>Spring also supports injection using the JSR-250
@@ -719,9 +723,9 @@ public @interface MovieQualifier {
<para>The name provided with the annotation is resolved as a bean name by
the <interfacename>ApplicationContext</interfacename> of which the
<classname>CommonAnnotationBeanPostProcessor</classname> is aware. The
names can be resolved through JNDI if you configure Spring's <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/jndi/support/SimpleJndiBeanFactory.html"
><classname>SimpleJndiBeanFactory</classname></ulink> explicitly.
names can be resolved through JNDI if you configure Spring's <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/jndi/support/SimpleJndiBeanFactory.html"
><classname>SimpleJndiBeanFactory</classname></link> explicitly.
However, it is recommended that you rely on the default behavior and
simply use Spring's JNDI lookup capabilities to preserve the level of
indirection.</para>
@@ -760,7 +764,7 @@ public @interface MovieQualifier {
}</programlisting>
</section>
<section id="beans-postconstruct-and-predestroy-annotations">
<section xml:id="beans-postconstruct-and-predestroy-annotations">
<title><interfacename>@PostConstruct</interfacename> and
<interfacename>@PreDestroy</interfacename></title>

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-classpath-scanning"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-classpath-scanning">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Classpath scanning and managed components</title>
<para>Most examples in this chapter use XML to specify the configuration
@@ -22,9 +26,9 @@
definitions registered with the container.</para>
<note>
<para>Starting with Spring 3.0, many features provided by the <ulink
url="http://www.springsource.org/javaconfig">Spring JavaConfig
project</ulink> are part of the core Spring Framework. This allows you to
<para>Starting with Spring 3.0, many features provided by the <link
xl:href="http://www.springsource.org/javaconfig">Spring JavaConfig
project</link> are part of the core Spring Framework. This allows you to
define beans using Java rather than using the traditional XML files. Take
a look at the <interfacename>@Configuration</interfacename>,
<interfacename>@Bean</interfacename>,
@@ -33,7 +37,7 @@
to use these new features.</para>
</note>
<section id="beans-stereotype-annotations">
<section xml:id="beans-stereotype-annotations">
<title><interfacename>@Component</interfacename> and further stereotype
annotations</title>
@@ -73,7 +77,7 @@
persistence layer.</para>
</section>
<section id="beans-scanning-autodetection">
<section xml:id="beans-scanning-autodetection">
<title>Automatically detecting classes and registering bean
definitions</title>
@@ -155,7 +159,7 @@ public class JpaMovieFinder implements MovieFinder {
-->
</section>
<section id="beans-scanning-filters">
<section xml:id="beans-scanning-filters">
<title>Using filters to customize scanning</title>
<para>By default, classes annotated with
@@ -172,7 +176,7 @@ public class JpaMovieFinder implements MovieFinder {
<literal>expression</literal> attributes. The following table describes
the filtering options.</para>
<table id="beans-scanning-filters-tbl">
<table xml:id="beans-scanning-filters-tbl">
<title>Filter Types</title>
<tgroup cols="3">
@@ -268,7 +272,7 @@ public class JpaMovieFinder implements MovieFinder {
</note>
</section>
<section id="beans-factorybeans-annotations">
<section xml:id="beans-factorybeans-annotations">
<title>Defining bean metadata within components</title>
<para>Spring components can also contribute bean definition metadata to the
@@ -358,7 +362,7 @@ public class FactoryMethodComponent {
semantics.</para>
</section>
<section id="beans-scanning-name-generator">
<section xml:id="beans-scanning-name-generator">
<title>Naming autodetected components</title>
<para>When a component is autodetected as part of the scanning process, its
@@ -390,9 +394,9 @@ public class MovieFinderImpl implements MovieFinder {
<note>
<para>If you do not want to rely on the default bean-naming strategy, you
can provide a custom bean-naming strategy. First, implement the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/support/BeanNameGenerator.html"
><interfacename>BeanNameGenerator</interfacename></ulink> interface, and
can provide a custom bean-naming strategy. First, implement the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/support/BeanNameGenerator.html"
><interfacename>BeanNameGenerator</interfacename></link> interface, and
be sure to include a default no-arg constructor. Then, provide the
fully-qualified class name when configuring the scanner:</para>
</note>
@@ -410,7 +414,7 @@ public class MovieFinderImpl implements MovieFinder {
is responsible for wiring.</para>
</section>
<section id="beans-scanning-scope-resolver">
<section xml:id="beans-scanning-scope-resolver">
<title>Providing a scope for autodetected components</title>
<para>As with Spring-managed components in general, the default and most
@@ -427,9 +431,9 @@ public class MovieFinderImpl implements MovieFinder {
<note>
<para>To provide a custom strategy for scope resolution rather than
relying on the annotation-based approach, implement the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/context/annotation/ScopeMetadataResolver.html"
><interfacename>ScopeMetadataResolver</interfacename></ulink> interface,
relying on the annotation-based approach, implement the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/context/annotation/ScopeMetadataResolver.html"
><interfacename>ScopeMetadataResolver</interfacename></link> interface,
and be sure to include a default no-arg constructor. Then, provide the
fully-qualified class name when configuring the scanner:</para>
</note>
@@ -457,7 +461,7 @@ public class MovieFinderImpl implements MovieFinder {
&lt;/beans&gt;</programlisting>
</section>
<section id="beans-scanning-qualifiers">
<section xml:id="beans-scanning-qualifiers">
<title>Providing qualifier metadata with annotations</title>
<para>The <interfacename>@Qualifier</interfacename> annotation is discussed

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="context-introduction"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="context-introduction">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Additional Capabilities of the
<interfacename>ApplicationContext</interfacename></title>
@@ -12,9 +16,9 @@
<literal>org.springframework.beans.factory</literal> package provides basic
functionality for managing and manipulating beans, including in a
programmatic way. The <literal>org.springframework.context</literal> package
adds the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/context/ApplicationContext.html"
><interfacename>ApplicationContext</interfacename></ulink> interface, which
adds the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/context/ApplicationContext.html"
><interfacename>ApplicationContext</interfacename></link> interface, which
extends the <interfacename>BeanFactory</interfacename> interface, in
addition to extending other interfaces to provide additional functionality
in a more <emphasis>application framework-oriented style</emphasis>. Many
@@ -56,7 +60,7 @@
</listitem>
</itemizedlist>
<section id="context-functionality-messagesource">
<section xml:id="context-functionality-messagesource">
<title>Internationalization using
<interfacename>MessageSource</interfacename></title>
@@ -181,12 +185,12 @@ argument.required=The '{0}' argument is required.</programlisting>
<programlisting language="xml">&lt;beans&gt;
<lineannotation>&lt;!-- this <interfacename>MessageSource</interfacename> is being used in a web application --&gt;</lineannotation>
<lineannotation>&lt;!-- this MessageSource is being used in a web application --&gt;</lineannotation>
&lt;bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"&gt;
&lt;property name="basename" value="exceptions"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- lets inject the above <interfacename>MessageSource</interfacename> into this POJO --&gt;</lineannotation>
<lineannotation>&lt;!-- lets inject the above MessageSource into this POJO --&gt;</lineannotation>
&lt;bean id="example" class="com.foo.Example"&gt;
&lt;property name="messages" ref="messageSource"/&gt;
&lt;/bean&gt;
@@ -267,7 +271,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
</note>
</section>
<section id="context-functionality-events">
<section xml:id="context-functionality-events">
<title>Standard and Custom Events</title>
<para>Event handling in the
@@ -281,7 +285,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
Essentially, this is the standard <emphasis>Observer</emphasis> design
pattern. Spring provides the following standard events:</para>
<table id="beans-ctx-events-tbl">
<table xml:id="beans-ctx-events-tbl">
<title>Built-in Events</title>
<tgroup cols="2">
@@ -492,16 +496,16 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
<para>Spring's eventing mechanism is designed for simple communication
between Spring beans within the same application context. However, for
more sophisticated enterprise integration needs, the
separately-maintained <ulink
url="http://springsource.org/spring-integration">Spring
Integration</ulink> project provides complete support for building
lightweight, <ulink url="http://www.enterpriseintegrationpatterns.com"
>pattern-oriented</ulink>, event-driven architectures that build upon
separately-maintained <link
xl:href="http://springsource.org/spring-integration">Spring
Integration</link> project provides complete support for building
lightweight, <link xl:href="http://www.enterpriseintegrationpatterns.com"
>pattern-oriented</link>, event-driven architectures that build upon
the well-known Spring programming model.</para>
</note>
</section>
<section id="context-functionality-resources">
<section xml:id="context-functionality-resources">
<title>Convenient access to low-level resources</title>
<para>For optimal usage and understanding of application contexts, users
@@ -548,7 +552,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
from the classpath or a URL, regardless of the actual context type.</para>
</section>
<section id="context-create">
<section xml:id="context-create">
<title>Convenient <interfacename>ApplicationContext</interfacename>
instantiation for web applications</title>
@@ -585,7 +589,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
&lt;/listener&gt;
<lineannotation>&lt;!-- or use the <classname>ContextLoaderServlet</classname> instead of the above listener</lineannotation><emphasis>
<lineannotation>&lt;!-- or use the ContextLoaderServlet instead of the above listener</lineannotation><emphasis>
&lt;servlet&gt;
&lt;servlet-name&gt;context&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt;
@@ -611,7 +615,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
does.</para>
</section>
<section id="context-deploy-rar">
<section xml:id="context-deploy-rar">
<title>Deploying a Spring ApplicationContext as a J2EE RAR file</title>
<para>In Spring 2.5 and later, it is possible to deploy a Spring
@@ -634,9 +638,9 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</
application server's JCA WorkManager through Spring's
<interfacename>TaskExecutor</interfacename> abstraction.</para>
<para>Check out the JavaDoc of the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/jca/context/SpringContextResourceAdapter.html"
>SpringContextResourceAdapter</ulink> class for the configuration details
<para>Check out the JavaDoc of the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/jca/context/SpringContextResourceAdapter.html"
>SpringContextResourceAdapter</link> class for the configuration details
involved in RAR deployment.</para>
<para><emphasis>For a simple deployment of a Spring ApplicationContext as a

View File

@@ -1,11 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
<section xml:id="beans-factory-nature"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-factory-nature">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xl="http://www.w3.org/1999/xlink"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Customizing the nature of a bean</title>
<section id="beans-factory-lifecycle">
<section xml:id="beans-factory-lifecycle">
<title>Lifecycle callbacks</title>
<!-- MLP Beverly to review: Old Text: The Spring Framework provides several callback interfaces to
@@ -38,7 +43,7 @@
<para>The lifecycle callback interfaces are described in this
section.</para>
<section id="beans-factory-lifecycle-initializingbean">
<section xml:id="beans-factory-lifecycle-initializingbean">
<title>Initialization callbacks</title>
<para>The
@@ -81,7 +86,7 @@
<para>... but does not couple the code to Spring.</para>
</section>
<section id="beans-factory-lifecycle-disposablebean">
<section xml:id="beans-factory-lifecycle-disposablebean">
<title>Destruction callbacks</title>
<para>Implementing the
@@ -123,7 +128,7 @@
<para>... but does not couple the code to Spring.</para>
</section>
<section id="beans-factory-lifecycle-default-init-destroy-methods">
<section xml:id="beans-factory-lifecycle-default-init-destroy-methods">
<title>Default initialization and destroy methods</title>
<para>When you write initialization and destroy method callbacks that do
@@ -208,7 +213,7 @@
bean.</para>
</section>
<section id="beans-factory-lifecycle-combined-effects">
<section xml:id="beans-factory-lifecycle-combined-effects">
<title>Combining lifecycle mechanisms</title>
<para>As of Spring 2.5, you have three options for controlling bean
@@ -274,7 +279,7 @@
</itemizedlist>
</section>
<section id="beans-factory-lifecycle-processor">
<section xml:id="beans-factory-lifecycle-processor">
<title>Startup and shutdown callbacks</title>
<para>The <interfacename>Lifecycle</interfacename> interface defines the
@@ -390,7 +395,7 @@ public interface SmartLifecycle extends Lifecycle, Phased {
way as described above.</para>
</section>
<section id="beans-factory-shutdown">
<section xml:id="beans-factory-shutdown">
<title>Shutting down the Spring IoC container gracefully in non-web
applications</title>
@@ -433,7 +438,7 @@ public final class Boot {
</section>
</section>
<section id="beans-factory-aware">
<section xml:id="beans-factory-aware">
<title><interfacename>ApplicationContextAware</interfacename> and
<interfacename>BeanNameAware</interfacename></title>
@@ -494,7 +499,7 @@ public final class Boot {
<emphasis>afterPropertiesSet</emphasis> or a custom init-method.</para>
</section>
<section id="aware-list">
<section xml:id="aware-list">
<title>Other <interfacename>Aware</interfacename> interfaces</title>
<para>Besides <interfacename>ApplicationContextAware</interfacename> and
@@ -507,7 +512,7 @@ public final class Boot {
a general rule, the name is a good indication of the dependency
type:</para>
<table id="beans-factory-nature-aware-list" pgwide="1">
<table xml:id="beans-factory-nature-aware-list" pgwide="1">
<title><interfacename>Aware</interfacename> interfaces</title>
<tgroup cols="3">

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-dependencies"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-dependencies">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Dependencies</title>
<para>A typical enterprise application does not consist of a single object (or
@@ -12,7 +16,7 @@
bean definitions that stand alone to a fully realized application where
objects collaborate to achieve a goal.</para>
<section id="beans-factory-collaborators">
<section xml:id="beans-factory-collaborators">
<title>Dependency injection</title>
<!-- MLP: Beverly review the following two paragraphs -->
@@ -41,7 +45,7 @@
injection</link> and <link linkend="beans-setter-injection">Setter-based
dependency injection</link>.</para>
<section id="beans-constructor-injection">
<section xml:id="beans-constructor-injection">
<title>Constructor-based dependency injection</title>
<para><emphasis>Constructor-based</emphasis> DI is accomplished by the
@@ -58,18 +62,18 @@
<programlisting language="java">public class SimpleMovieLister {
<lineannotation>// the <classname>SimpleMovieLister</classname> has a dependency on a <interfacename>MovieFinder</interfacename></lineannotation>
<lineannotation>// the SimpleMovieLister has a dependency on a MovieFinder</lineannotation>
private MovieFinder movieFinder;
<lineannotation>// a constructor so that the Spring container can 'inject' a <interfacename>MovieFinder</interfacename></lineannotation>
<lineannotation>// a constructor so that the Spring container can 'inject' a MovieFinder</lineannotation>
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// business logic that actually 'uses' the injected <interfacename>MovieFinder</interfacename> is omitted...</lineannotation>
<lineannotation>// business logic that actually 'uses' the injected MovieFinder is omitted...</lineannotation>
}</programlisting>
<section id="beans-factory-ctor-arguments-resolution">
<section xml:id="beans-factory-ctor-arguments-resolution">
<title>Constructor argument resolution</title>
<para>Constructor argument resolution matching occurs using the
@@ -129,7 +133,7 @@ public class ExampleBean {
}
}</programlisting>
<section id="beans-factory-ctor-arguments-type">
<section xml:id="beans-factory-ctor-arguments-type">
<title>Constructor argument type matching</title>
<para>In the preceding scenario, the container
@@ -143,7 +147,7 @@ public class ExampleBean {
&lt;/bean&gt;</programlisting>
</section>
<section id="beans-factory-ctor-arguments-index">
<section xml:id="beans-factory-ctor-arguments-index">
<title>Constructor argument index</title>
<para>Use the <literal>index</literal> attribute to specify explicitly
@@ -160,7 +164,7 @@ public class ExampleBean {
0 based</emphasis>.</para>
</section>
<section id="beans-factory-ctor-arguments-name">
<section xml:id="beans-factory-ctor-arguments-name">
<title>Constructor argument name</title>
<para>As of Spring 3.0 you can also use the constructor parameter
@@ -175,8 +179,8 @@ public class ExampleBean {
must be compiled with the debug flag enabled so that Spring can
look up the parameter name from the constructor. If you can't compile
your code with debug flag (or don't want to) you can use
<interfacename><ulink
url="http://download.oracle.com/javase/6/docs/api/java/beans/ConstructorProperties.html">@ConstructorProperties</ulink></interfacename>
<interfacename><link
xl:href="http://download.oracle.com/javase/6/docs/api/java/beans/ConstructorProperties.html">@ConstructorProperties</link></interfacename>
JDK annotation to explicitly name your constructor arguments. The
sample class would then have to look as follows:</para>
@@ -196,7 +200,7 @@ public class ExampleBean {
</section>
</section>
<section id="beans-setter-injection">
<section xml:id="beans-setter-injection">
<title>Setter-based dependency injection</title>
<para><emphasis>Setter-based</emphasis> DI is accomplished by the
@@ -211,15 +215,15 @@ public class ExampleBean {
<programlisting language="java">public class SimpleMovieLister {
<lineannotation>// the <classname>SimpleMovieLister</classname> has a dependency on the <interfacename>MovieFinder</interfacename></lineannotation>
<lineannotation>// the SimpleMovieLister has a dependency on the MovieFinder</lineannotation>
private MovieFinder movieFinder;
<lineannotation>// a setter method so that the Spring container can 'inject' a <interfacename>MovieFinder</interfacename></lineannotation>
<lineannotation>// a setter method so that the Spring container can 'inject' a MovieFinder</lineannotation>
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
<lineannotation>// business logic that actually 'uses' the injected <interfacename>MovieFinder</interfacename> is omitted...</lineannotation>
<lineannotation>// business logic that actually 'uses' the injected MovieFinder is omitted...</lineannotation>
}</programlisting>
<para>The <interfacename>ApplicationContext</interfacename> supports
@@ -265,7 +269,7 @@ public class ExampleBean {
</sidebar>
</section>
<section id="beans-dependency-resolution">
<section xml:id="beans-dependency-resolution">
<title>Dependency resolution process</title>
<para>The container performs bean dependency resolution as follows:</para>
@@ -371,7 +375,7 @@ public class ExampleBean {
callback method</link>) are invoked.</para>
</section>
<section id="beans-some-examples">
<section xml:id="beans-some-examples">
<title>Examples of dependency injection</title>
<para>The following example uses XML-based configuration metadata for
@@ -380,7 +384,7 @@ public class ExampleBean {
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"&gt;
<lineannotation>&lt;!-- setter injection using the nested <literal>&lt;ref/&gt;</literal> element --&gt;</lineannotation>
<lineannotation>&lt;!-- setter injection using the nested &lt;ref/&gt; element --&gt;</lineannotation>
&lt;property name="beanOne"&gt;&lt;ref bean="anotherExampleBean"/&gt;&lt;/property&gt;
<lineannotation>&lt;!-- setter injection using the neater 'ref' attribute --&gt;</lineannotation>
@@ -416,7 +420,7 @@ public class ExampleBean {
<programlisting language="xml">&lt;bean id="exampleBean" class="examples.ExampleBean"&gt;
<lineannotation>&lt;!-- constructor injection using the nested <literal>&lt;ref/&gt;</literal> element --&gt;</lineannotation>
<lineannotation>&lt;!-- constructor injection using the nested &lt;ref/&gt; element --&gt;</lineannotation>
&lt;constructor-arg&gt;
&lt;ref bean="anotherExampleBean"/&gt;
&lt;/constructor-arg&gt;
@@ -494,7 +498,7 @@ public class ExampleBean {
</section>
</section>
<section id="beans-factory-properties-detailed">
<section xml:id="beans-factory-properties-detailed">
<title>Dependencies and configuration in detail</title>
<para>As mentioned in the previous section, you can define bean properties
@@ -505,7 +509,7 @@ public class ExampleBean {
<literal>&lt;constructor-arg/&gt;</literal> elements for this
purpose.</para>
<section id="beans-value-element">
<section xml:id="beans-value-element">
<title>Straight values (primitives, <literal>Strings</literal>, and so
on)</title>
@@ -519,7 +523,7 @@ public class ExampleBean {
<programlisting language="xml">&lt;bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
<lineannotation>&lt;!-- results in a <methodname>setDriverClassName(String)</methodname> call --&gt;</lineannotation>
<lineannotation>&lt;!-- results in a setDriverClassName(String) call --&gt;</lineannotation>
&lt;property name="driverClassName" value="com.mysql.jdbc.Driver"/&gt;
&lt;property name="url" value="jdbc:mysql://localhost:3306/mydb"/&gt;
&lt;property name="username" value="root"/&gt;
@@ -547,10 +551,10 @@ public class ExampleBean {
</programlisting>
<para>The preceding XML is more succinct; however, typos are discovered at
runtime rather than design time, unless you use an IDE such as <ulink
url="http://www.jetbrains.com/idea/">IntelliJ IDEA</ulink> or the <ulink
url="http://www.springsource.com/products/sts">SpringSource Tool
Suite</ulink> (STS) that support automatic property completion when you
runtime rather than design time, unless you use an IDE such as <link
xl:href="http://www.jetbrains.com/idea/">IntelliJ IDEA</link> or the <link
xl:href="http://www.springsource.com/products/sts">SpringSource Tool
Suite</link> (STS) that support automatic property completion when you
create bean definitions. Such IDE assistance is highly
recommended.</para>
@@ -560,7 +564,7 @@ public class ExampleBean {
<programlisting language="xml">&lt;bean id="mappings"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
<lineannotation>&lt;!-- typed as a <classname>java.util.Properties</classname> --&gt;</lineannotation>
<lineannotation>&lt;!-- typed as a java.util.Properties --&gt;</lineannotation>
&lt;property name="properties"&gt;
&lt;value&gt;
jdbc.driver.className=com.mysql.jdbc.Driver
@@ -577,7 +581,7 @@ public class ExampleBean {
favor the use of the nested <literal>&lt;value/&gt;</literal> element
over the <literal>value</literal> attribute style.</para>
<section id="beans-idref-element">
<section xml:id="beans-idref-element">
<title>The <literal>idref</literal> element</title>
<para>The <literal>idref</literal> element is simply an error-proof way
@@ -622,7 +626,7 @@ public class ExampleBean {
to validate the bean id earlier, at XML document parse time.</para>
<programlisting language="xml">&lt;property name="targetName"&gt;
<lineannotation>&lt;!-- a bean with id '<literal>theTargetBean</literal>' must exist; otherwise an exception will be thrown --&gt;</lineannotation>
<lineannotation>&lt;!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown --&gt;</lineannotation>
&lt;idref local="theTargetBean"/&gt;
&lt;/property&gt;</programlisting>
@@ -635,7 +639,7 @@ public class ExampleBean {
</section>
</section>
<section id="beans-ref-element">
<section xml:id="beans-ref-element">
<title>References to other beans (collaborators)</title>
<para>The <literal>ref</literal> element is the final element inside a
@@ -649,7 +653,7 @@ public class ExampleBean {
container.) All references are ultimately a reference to another object.
Scoping and validation depend on whether you specify the id/name of the
other object through the
<literal>bean,<literal>local,</literal></literal> or
<literal>bean</literal>,<literal>local,</literal> or
<literal>parent</literal> attributes.</para>
<para>Specifying the target bean through the <literal>bean</literal>
@@ -701,7 +705,7 @@ public class ExampleBean {
&lt;/bean&gt;</programlisting>
</section>
<section id="beans-inner-beans">
<section xml:id="beans-inner-beans">
<title>Inner beans</title>
<para>A <literal>&lt;bean/&gt;</literal> element inside the
@@ -729,7 +733,7 @@ public class ExampleBean {
collaborating beans other than into the enclosing bean.</para>
</section>
<section id="beans-collection-elements">
<section xml:id="beans-collection-elements">
<title>Collections</title>
<para>In the <literal>&lt;list/&gt;</literal>,
@@ -741,7 +745,7 @@ public class ExampleBean {
<interfacename>Properties</interfacename>, respectively.</para>
<programlisting language="xml">&lt;bean id="moreComplexObject" class="example.ComplexObject"&gt;
<lineannotation>&lt;!-- results in a setAdminEmails(<classname>java.util.Properties</classname>) call --&gt;</lineannotation>
<lineannotation>&lt;!-- results in a setAdminEmails(java.util.Properties) call --&gt;</lineannotation>
&lt;property name="adminEmails"&gt;
&lt;props&gt;
&lt;prop key="administrator"&gt;administrator@example.org&lt;/prop&gt;
@@ -749,14 +753,14 @@ public class ExampleBean {
&lt;prop key="development"&gt;development@example.org&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
<lineannotation>&lt;!-- results in a setSomeList(<interfacename>java.util.List</interfacename>) call --&gt;</lineannotation>
<lineannotation>&lt;!-- results in a setSomeList(java.util.List) call --&gt;</lineannotation>
&lt;property name="someList"&gt;
&lt;list&gt;
&lt;value&gt;a list element followed by a reference&lt;/value&gt;
&lt;ref bean="myDataSource" /&gt;
&lt;/list&gt;
&lt;/property&gt;
<lineannotation>&lt;!-- results in a setSomeMap(<interfacename>java.util.Map</interfacename>) call --&gt;</lineannotation>
<lineannotation>&lt;!-- results in a setSomeMap(java.util.Map) call --&gt;</lineannotation>
&lt;property name="someMap"&gt;
&lt;map&gt;
&lt;entry key="an entry" value="just some string"/&gt;
@@ -777,7 +781,7 @@ public class ExampleBean {
<programlisting language="xml">bean | ref | idref | list | set | map | props | value | null</programlisting>
<section id="beans-collection-elements-merging">
<section xml:id="beans-collection-elements-merging">
<title>Collection merging</title>
<para>As of Spring 2.0, the container supports the
@@ -859,7 +863,7 @@ support=support@example.co.uk</programlisting>
the container uses internally.</para>
</section>
<section id="beans-collection-merge-limitations">
<section xml:id="beans-collection-merge-limitations">
<title>Limitations of collection merging</title>
<para>You cannot merge different collection types (such as a
@@ -873,7 +877,7 @@ support=support@example.co.uk</programlisting>
in Spring 2.0 and later.</para>
</section>
<section id="beans-collection-elements-strongly-typed">
<section xml:id="beans-collection-elements-strongly-typed">
<title>Strongly-typed collection (Java 5+ only)</title>
<para>In Java 5 and later, you can use strongly typed collections (using
@@ -920,7 +924,7 @@ support=support@example.co.uk</programlisting>
</section>
</section>
<section id="beans-null-element">
<section xml:id="beans-null-element">
<title>Null and empty string values</title>
<para><!--Clarify difference between null value and empty string value?-->Spring
@@ -946,7 +950,7 @@ support=support@example.co.uk</programlisting>
<methodname>exampleBean.setEmail(null)</methodname>.</para>
</section>
<section id="beans-p-namespace">
<section xml:id="beans-p-namespace">
<title>XML shortcut with the p-namespace</title>
<para>The p-namespace enables you to use the <literal>bean</literal>
@@ -1030,26 +1034,26 @@ support=support@example.co.uk</programlisting>
time.<!--Clarify ref to all three approaches.I see two, XML and namespace.--></para>
</note>
</section>
<section id="beans-c-namespace">
<section xml:id="beans-c-namespace">
<title>XML shortcut with the c-namespace</title>
<para>Similar to the <xref linkend="beans-p-namespace"/>, the <emphasis>c-namespace</emphasis>, newly introduced in Spring 3.1,
<para>Similar to the <xref linkend="beans-p-namespace"/>, the <emphasis>c-namespace</emphasis>, newly introduced in Spring 3.1,
allows usage of inlined attributes for configuring the constructor arguments rather then nested <literal>constructor-arg</literal>
elements.</para>
<para>Let's review the examples from <xref linkend="beans-constructor-injection"/> with the <literal>c</literal> namespace:</para>
<programlisting language="java">&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
&lt;bean id="bar" class="x.y.Bar"/&gt;
&lt;bean id="baz" class="x.y.Baz"/&gt;
&lt;-- 'traditional' declaration --&gt;
&lt;-- 'traditional' declaration --&gt;
&lt;bean id="foo" class="x.y.Foo"&gt;
&lt;constructor-arg ref="bar"/&gt;
&lt;constructor-arg ref="baz"/&gt;
@@ -1061,24 +1065,24 @@ support=support@example.co.uk</programlisting>
&lt;/beans&gt;</programlisting>
<para>The <literal>c:</literal> namespace uses the same conventions as the <literal>p:</literal> one (trailing <literal>-ref</literal> for bean references)
for setting the constructor arguments by their names. And just as well, it needs to be declared even though it is not defined in an XSD schema
(but it exists inside the Spring core).</para>
<para>For the rare cases where the constructor argument names are not available (usually if the bytecode was compiled without debugging information), one can
use fallback to the argument indexes:</para>
<para>The <literal>c:</literal> namespace uses the same conventions as the <literal>p:</literal> one (trailing <literal>-ref</literal> for bean references)
for setting the constructor arguments by their names. And just as well, it needs to be declared even though it is not defined in an XSD schema
(but it exists inside the Spring core).</para>
<para>For the rare cases where the constructor argument names are not available (usually if the bytecode was compiled without debugging information), one can
use fallback to the argument indexes:</para>
<programlisting language="java">&lt;-- 'c-namespace' index declaration --&gt;
&lt;bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz"&gt;</programlisting>
<note>Due to the XML grammar, the index notation requires the presence of the leading <emphasis>_</emphasis> as XML attribute names cannot start
with a number (even though some IDE allow it).</note>
<para>In practice, the constructor resolution <link linkend="beans-factory-ctor-arguments-resolution">mechanism</link> is quite efficient in matching arguments so
unless one really needs to, we recommend using the name notation through-out your configuration.</para>
<note><para>Due to the XML grammar, the index notation requires the presence of the leading <emphasis>_</emphasis> as XML attribute names cannot start
with a number (even though some IDE allow it).</para></note>
<para>In practice, the constructor resolution <link linkend="beans-factory-ctor-arguments-resolution">mechanism</link> is quite efficient in matching arguments so
unless one really needs to, we recommend using the name notation through-out your configuration.</para>
</section>
<section id="beans-compound-property-names">
<section xml:id="beans-compound-property-names">
<title>Compound property names</title>
<para>You can use compound or nested property names when you set bean
@@ -1102,7 +1106,7 @@ support=support@example.co.uk</programlisting>
</section>
</section>
<section id="beans-factory-dependson">
<section xml:id="beans-factory-dependson">
<title>Using <literal>depends-on</literal></title>
<para>If a bean is a dependency of another that usually means that one bean
@@ -1144,7 +1148,7 @@ support=support@example.co.uk</programlisting>
</note>
</section>
<section id="beans-factory-lazy-init">
<section xml:id="beans-factory-lazy-init">
<title>Lazy-initialized
beans<!--Changed to lazy-initialized from lazily instantiated because attribute is lazy-init, and there was a lot of inconsistency. --></title>
@@ -1190,7 +1194,7 @@ support=support@example.co.uk</programlisting>
&lt;/beans&gt;</programlisting>
</section>
<section id="beans-factory-autowire">
<section xml:id="beans-factory-autowire">
<title>Autowiring collaborators</title>
<!--I've moved around info and done a lot of editing/reformatting in this section, but nothing is missing.-->
@@ -1225,7 +1229,7 @@ support=support@example.co.uk</programlisting>
five modes. You specify autowiring <emphasis>per</emphasis> bean and thus
can choose which ones to autowire.</para>
<table id="beans-factory-autowiring-modes-tbl">
<table xml:id="beans-factory-autowiring-modes-tbl">
<title>Autowiring modes</title>
<tgroup cols="2">
@@ -1301,7 +1305,7 @@ support=support@example.co.uk</programlisting>
<para>You can combine autowire behavior with dependency checking, which is
performed after autowiring completes.</para>
<section id="beans-autowired-exceptions">
<section xml:id="beans-autowired-exceptions">
<title>Limitations and disadvantages of autowiring</title>
<para>Autowiring works best when it is used consistently across a project.
@@ -1377,7 +1381,7 @@ support=support@example.co.uk</programlisting>
</itemizedlist>
</section>
<section id="beans-factory-autowire-candidate">
<section xml:id="beans-factory-autowire-candidate">
<title>Excluding a bean from autowiring</title>
<para>On a per-bean basis, you can exclude a bean from autowiring. In
@@ -1410,7 +1414,7 @@ support=support@example.co.uk</programlisting>
</section>
</section>
<section id="beans-factory-method-injection">
<section xml:id="beans-factory-method-injection">
<title>Method injection</title>
<para>In most application scenarios, most beans in the container are <link
@@ -1446,9 +1450,9 @@ public class CommandManager implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Object process(Map commandState) {
<lineannotation>// grab a new instance of the appropriate <interfacename>Command</interfacename></lineannotation>
<lineannotation>// grab a new instance of the appropriate Command</lineannotation>
Command command = createCommand();
<lineannotation>// set the state on the (hopefully brand new) <interfacename>Command</interfacename> instance</lineannotation>
<lineannotation>// set the state on the (hopefully brand new) Command instance</lineannotation>
command.setState(commandState);
return command.execute();
}
@@ -1472,11 +1476,11 @@ public class CommandManager implements ApplicationContextAware {
<sidebar>
<para>You can read more about the motivation for Method Injection in
<ulink url="http://blog.springsource.com/2004/08/06/method-injection/"
>this blog entry</ulink>.</para>
<link xl:href="http://blog.springsource.com/2004/08/06/method-injection/"
>this blog entry</link>.</para>
</sidebar>
<section id="beans-factory-lookup-method-injection">
<section xml:id="beans-factory-lookup-method-injection">
<title>Lookup method injection</title>
<!--Deleted a box here that doesn't seem to have much info; I moved the blog entry link above. -->
@@ -1519,9 +1523,9 @@ public class CommandManager implements ApplicationContextAware {
public abstract class CommandManager {
public Object process(Object commandState) {
<lineannotation>// grab a new instance of the appropriate <interfacename>Command</interfacename> interface</lineannotation>
<lineannotation>// grab a new instance of the appropriate Command interface</lineannotation>
Command command = createCommand();
<lineannotation>// set the state on the (hopefully brand new) <interfacename>Command</interfacename> instance</lineannotation>
<lineannotation>// set the state on the (hopefully brand new) Command instance</lineannotation>
command.setState(commandState);
return command.execute();
}
@@ -1546,7 +1550,7 @@ public abstract class CommandManager {
<lineannotation>&lt;!-- inject dependencies here as required --&gt;</lineannotation>
&lt;/bean&gt;
<lineannotation>&lt;!-- <literal>commandProcessor</literal> uses <literal>statefulCommandHelper</literal> --&gt;</lineannotation>
<lineannotation>&lt;!-- commandProcessor uses statefulCommandHelper --&gt;</lineannotation>
&lt;bean id="commandManager" class="fiona.apple.CommandManager"&gt;
&lt;lookup-method name="createCommand" bean="command"/&gt;
&lt;/bean&gt;</programlisting>
@@ -1569,14 +1573,14 @@ public abstract class CommandManager {
<classname>ObjectFactoryCreatingFactoryBean</classname>, but it allows
you to specify your own lookup interface as opposed to a
Spring-specific lookup interface. Consult the JavaDocs for these
classes as well as this <ulink
url="http://blog.arendsen.net/index.php/2006/10/05/on-the-servicelocatorfactorybean-dlas-and-the-sustainability-of-code-and-design/"
>blog entry</ulink> for additional information
classes as well as this <link
xl:href="http://blog.arendsen.net/index.php/2006/10/05/on-the-servicelocatorfactorybean-dlas-and-the-sustainability-of-code-and-design/"
>blog entry</link> for additional information
ServiceLocatorFactoryBean.</para>
</tip>
</section>
<section id="beans-factory-arbitrary-method-replacement">
<section xml:id="beans-factory-arbitrary-method-replacement">
<title>Arbitrary method replacement</title>
<para>A less useful form of method injection than lookup method Injection
@@ -1604,8 +1608,8 @@ public String computeValue(String input) {
<interfacename>org.springframework.beans.factory.support.MethodReplacer</interfacename>
interface provides the new method definition.</para>
<programlisting language="java"><lineannotation>/** meant to be used to override the existing <methodname>computeValue(String)</methodname>
implementation in <classname>MyValueCalculator</classname>
<programlisting language="java"><lineannotation>/** meant to be used to override the existing computeValue(String)
implementation in MyValueCalculator
*/</lineannotation>
public class ReplacementComputeValue implements MethodReplacer {

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-factory-extension"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-factory-extension">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Container Extension Points</title>
<para>Typically, an application developer does not need to subclass
@@ -11,7 +15,7 @@
implementations of special integration interfaces. The next few sections
describe these integration interfaces.</para>
<section id="beans-factory-extension-bpp">
<section xml:id="beans-factory-extension-bpp">
<title>Customizing beans using a
<interfacename>BeanPostProcessor</interfacename></title>
@@ -85,7 +89,7 @@
Bean post-processors can be deployed in the container just like any other
beans.</para>
<anchor id="beans-factory-programmatically-registering-beanpostprocessors"/>
<anchor xml:id="beans-factory-programmatically-registering-beanpostprocessors"/>
<note>
<title>Programmatically registering <interfacename>BeanPostProcessors
</interfacename></title>
@@ -137,7 +141,7 @@
<literal>BeanPostProcessors</literal> in an
<interfacename>ApplicationContext</interfacename>.</para>
<section id="beans-factory-extension-bpp-examples-hw">
<section xml:id="beans-factory-extension-bpp-examples-hw">
<title>Example: Hello World,
<interfacename>BeanPostProcessor</interfacename>-style</title>
@@ -187,7 +191,7 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor
<lineannotation>&lt;!--
when the above bean (messenger) is instantiated, this custom
<interfacename>BeanPostProcessor</interfacename> implementation will output the fact to the system console
BeanPostProcessor implementation will output the fact to the system console
--&gt;</lineannotation>
&lt;bean class="scripting.InstantiationTracingBeanPostProcessor"/&gt;
@@ -224,7 +228,7 @@ public final class Boot {
org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting>
</section>
<section id="beans-factory-extension-bpp-examples-rabpp">
<section xml:id="beans-factory-extension-bpp-examples-rabpp">
<title>Example: The
<classname>RequiredAnnotationBeanPostProcessor</classname></title>
@@ -239,7 +243,7 @@ org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting>
</section>
</section>
<section id="beans-factory-extension-factory-postprocessors">
<section xml:id="beans-factory-extension-factory-postprocessors">
<title>Customizing configuration metadata with a
<interfacename>BeanFactoryPostProcessor</interfacename></title>
@@ -299,7 +303,7 @@ org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting>
<interfacename>BeanFactoryPostProcessor</interfacename> can also be used,
for example, to register custom property editors.</para>
<anchor id="beans-factory-autodetect-beanfactorypostprocessors"/>
<anchor xml:id="beans-factory-autodetect-beanfactorypostprocessors"/>
<para>An <interfacename>ApplicationContext</interfacename> automatically
detects any beans that are deployed into it that implement the
@@ -314,14 +318,14 @@ org.springframework.scripting.groovy.GroovyMessenger@272961</programlisting>
for lazy initialization. If no other bean references a
<interfacename>Bean(Factory)PostProcessor</interfacename>,
that post-processor will not get instantiated at all. Thus, marking it for
lazy initialization will be ignored, and the
lazy initialization will be ignored, and the
<interfacename>Bean(Factory)PostProcessor</interfacename> will be
instantiated eagerly even if you set the <literal>default-lazy-init</literal>
attribute to <literal>true</literal> on the declaration of your
<code>&lt;beans /&gt;</code> element.</para>
</note>
<section id="beans-factory-placeholderconfigurer">
<section xml:id="beans-factory-placeholderconfigurer">
<title>Example: the
<interfacename>PropertyPlaceholderConfigurer</interfacename></title>
@@ -392,15 +396,15 @@ jdbc.password=root</programlisting>
</para>
<itemizedlist>
<listitem>
<para><emphasis>never</emphasis> (0): Never check system properties</para>
</listitem>
<listitem>
<para><emphasis>fallback</emphasis> (1): Check system properties if not resolvable in the specified properties files. This is the default.</para>
</listitem>
<listitem>
<para><emphasis>override</emphasis> (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source.</para>
</listitem>
<listitem>
<para><emphasis>never</emphasis> (0): Never check system properties</para>
</listitem>
<listitem>
<para><emphasis>fallback</emphasis> (1): Check system properties if not resolvable in the specified properties files. This is the default.</para>
</listitem>
<listitem>
<para><emphasis>override</emphasis> (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source.</para>
</listitem>
</itemizedlist>
<para>
@@ -434,7 +438,7 @@ jdbc.password=root</programlisting>
</tip>
</section>
<section id="beans-factory-overrideconfigurer">
<section xml:id="beans-factory-overrideconfigurer">
<title>Example: the
<classname>PropertyOverrideConfigurer</classname></title>
@@ -495,7 +499,7 @@ dataSource.url=jdbc:mysql:mydb</programlisting>
</section>
</section>
<section id="beans-factory-extension-factorybean">
<section xml:id="beans-factory-extension-factorybean">
<title>Customizing instantiation logic with a
<interfacename>FactoryBean</interfacename></title>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-java"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-java">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Java-based container configuration</title>
<section id="beans-java-basic-concepts">
<section xml:id="beans-java-basic-concepts">
<title>Basic concepts: <literal>@Configuration</literal> and
<literal>@Bean</literal></title>
@@ -41,7 +45,7 @@ public class AppConfig {
spring container using Java-based configuration.</para>
</section>
<section id="beans-java-instantiating-container">
<section xml:id="beans-java-instantiating-container">
<title>Instantiating the Spring container using
<literal>AnnotationConfigApplicationContext</literal></title>
@@ -63,7 +67,7 @@ public class AppConfig {
<literal>@Inject</literal> are used within those classes where
necessary.</para>
<section id="beans-java-instantiating-container-contstructor">
<section xml:id="beans-java-instantiating-container-contstructor">
<title>Simple construction</title>
<para>In much the same way that Spring XML files are used as input when
@@ -92,7 +96,7 @@ public class AppConfig {
<literal>@Autowired</literal>.</para>
</section>
<section id="beans-java-instantiating-container-register">
<section xml:id="beans-java-instantiating-container-register">
<title>Building the container programmatically using
<literal>register(Class&lt;?&gt;...)</literal></title>
@@ -111,7 +115,7 @@ public class AppConfig {
}</programlisting></para>
</section>
<section id="beans-java-instantiating-container-scan">
<section xml:id="beans-java-instantiating-container-scan">
<title>Enabling component scanning with
<literal>scan(String...)</literal></title>
@@ -148,7 +152,7 @@ public class AppConfig {
</note>
</section>
<section id="beans-java-instantiating-container-web">
<section xml:id="beans-java-instantiating-container-web">
<title>Support for web applications with
<literal>AnnotationConfigWebApplicationContext</literal></title>
@@ -214,10 +218,10 @@ public class AppConfig {
</section>
</section>
<section id="beans-java-composing-configuration-classes">
<section xml:id="beans-java-composing-configuration-classes">
<title>Composing Java-based configurations</title>
<section id="beans-java-using-import">
<section xml:id="beans-java-using-import">
<title>Using the <literal>@Import</literal> annotation</title>
<para>Much as the <literal>&lt;import/&gt;</literal> element is used
@@ -250,7 +254,7 @@ public class ConfigB {
a potentially large number of <literal>@Configuration</literal> classes
during construction.</para>
<section id="beans-java-injecting-imported-beans">
<section xml:id="beans-java-injecting-imported-beans">
<title>Injecting dependencies on imported <literal>@Bean</literal>
definitions</title>
@@ -304,7 +308,7 @@ public static void main(String[] args) {
transferService.transfer(100.00, "A123", "C456");
}</programlisting></para>
<section id="beans-java-injecting-imported-beans-fq">
<section xml:id="beans-java-injecting-imported-beans-fq">
<title>Fully-qualifying imported beans for ease of navigation</title>
<para>In the scenario above, using <literal>@Autowired</literal> works
@@ -314,8 +318,8 @@ public static void main(String[] args) {
<literal>ServiceConfig</literal>, how do you know exactly where the
<literal>@Autowired AccountRepository</literal> bean is declared?
It's not explicit in the code, and this may be just fine. Remember
that the <ulink url="http://www.springsource.com/products/sts"
>SpringSource Tool Suite</ulink> provides tooling that can render
that the <link xl:href="http://www.springsource.com/products/sts"
>SpringSource Tool Suite</link> provides tooling that can render
graphs showing how everything is wired up - that may be all you
need. Also, your Java IDE can easily find all declarations and uses
of the <literal>AccountRepository</literal> type, and will quickly
@@ -386,7 +390,7 @@ public static void main(String[] args) {
</section>
</section>
<section id="beans-java-combining">
<section xml:id="beans-java-combining">
<title>Combining Java and XML configuration</title>
<para>Spring's <literal>@Configuration</literal> class support does not
@@ -400,7 +404,7 @@ public static void main(String[] args) {
<literal>@ImportResource</literal> annotation to import XML as
needed.</para>
<section id="beans-java-combining-xml-centric">
<section xml:id="beans-java-combining-xml-centric">
<title>XML-centric use of <literal>@Configuration</literal>
classes</title>
@@ -413,7 +417,7 @@ public static void main(String[] args) {
<literal>@Configuration</literal> classes in this kind of
"XML-centric" situation.</para>
<section id="beans-java-combining-xml-centric-declare-as-bean">
<section xml:id="beans-java-combining-xml-centric-declare-as-bean">
<title>Declaring <literal>@Configuration</literal> classes as plain
Spring <literal>&lt;bean/&gt;</literal> elements</title>
@@ -476,7 +480,7 @@ jdbc.password=</programlisting>
</note>
</section>
<section id="beans-java-combining-xml-centric-component-scan">
<section xml:id="beans-java-combining-xml-centric-component-scan">
<title>Using <literal>&lt;context:component-scan/&gt;</literal> to
pick up <literal>@Configuration</literal> classes</title>
@@ -506,7 +510,7 @@ jdbc.password=</programlisting>
</section>
</section>
<section id="beans-java-combining-java-centric">
<section xml:id="beans-java-combining-java-centric">
<title><literal>@Configuration</literal> class-centric use of XML with
<literal>@ImportResource</literal></title>
@@ -544,7 +548,7 @@ jdbc.password=</programlisting>
</section>
</section>
<section id="beans-java-bean-annotation">
<section xml:id="beans-java-bean-annotation">
<title>Using the <interfacename>@Bean</interfacename> annotation</title>
<para><interfacename>@Bean</interfacename> is a method-level annotation and
@@ -562,7 +566,7 @@ jdbc.password=</programlisting>
<interfacename>@Configuration</interfacename>-annotated or in a
<interfacename>@Component</interfacename>-annotated class.</para>
<section id="beans-java-declaring-a-bean">
<section xml:id="beans-java-declaring-a-bean">
<title>Declaring a bean</title>
<para>To declare a bean, simply annotate a method with the
@@ -595,7 +599,7 @@ transferService -&gt; com.acme.TransferServiceImpl
</programlisting></para>
</section>
<section id="beans-java-injecting-dependencies">
<section xml:id="beans-java-injecting-dependencies">
<title>Injecting dependencies</title>
<para>When <interfacename>@Bean</interfacename>s have dependencies on one
@@ -620,7 +624,7 @@ public class AppConfig {
to <code> bar</code> via constructor injection.</para>
</section>
<section id="beans-java-lifecycle-callbacks">
<section xml:id="beans-java-lifecycle-callbacks">
<title>Receiving lifecycle callbacks</title>
<para>Beans declared in a
@@ -697,10 +701,10 @@ public class AppConfig {
</tip>
</section>
<section id="beans-java-specifying-bean-scope">
<section xml:id="beans-java-specifying-bean-scope">
<title>Specifying bean scope</title>
<section id="beans-java-available-scopes">
<section xml:id="beans-java-available-scopes">
<title>Using the <interfacename>@Scope</interfacename>
annotation</title>
@@ -724,7 +728,7 @@ public class MyConfiguration {
}</programlisting></para>
</section>
<section id="beans-java-scoped-proxy">
<section xml:id="beans-java-scoped-proxy">
<title><code>@Scope and scoped-proxy</code></title>
<para>Spring offers a convenient way of working with scoped dependencies
@@ -757,7 +761,7 @@ public Service userService() {
} </programlisting></para>
</section>
<section id="beans-java-method-injection">
<section xml:id="beans-java-method-injection">
<title>Lookup method injection</title>
<para>As noted earlier, <link linkend="beans-factory-method-injection"
@@ -804,7 +808,7 @@ public CommandManager commandManager() {
</section>
</section>
<section id="beans-java-customizing-bean-naming">
<section xml:id="beans-java-customizing-bean-naming">
<title>Customizing bean naming</title>
<para>By default, configuration classes use a
@@ -825,7 +829,7 @@ public class AppConfig {
<section id="beans-java-bean-aliasing">
<section xml:id="beans-java-bean-aliasing">
<title>Bean aliasing</title>
<para>As discussed in <xref linkend="beans-beanname"/>, it is sometimes
@@ -845,7 +849,7 @@ public class AppConfig {
</section>
</section>
<section id="beans-java-further-information-java-config">
<section xml:id="beans-java-further-information-java-config">
<title>Further information about how Java-based configuration works
internally</title>

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-factory-scopes"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-factory-scopes">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Bean scopes</title>
<para>When you create a bean definition, you create a
@@ -25,7 +29,7 @@
<para>The following scopes are supported out of the box. You can also create
<link linkend="beans-factory-scopes-custom">a custom scope.</link></para>
<table id="beans-factory-scopes-tbl">
<table xml:id="beans-factory-scopes-tbl">
<title>Bean scopes</title>
<tgroup cols="2">
@@ -94,14 +98,14 @@
<para>As of Spring 3.0, a <emphasis>thread scope</emphasis> is available,
but is not registered by default. For more information, see the
documentation for <ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/context/support/SimpleThreadScope.html"
>SimpleThreadScope</ulink>. For instructions on how to register this or
documentation for <link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/context/support/SimpleThreadScope.html"
>SimpleThreadScope</link>. For instructions on how to register this or
any other custom scope, see <xref
linkend="beans-factory-scopes-custom-using"/>.</para>
</note>
<section id="beans-factory-scopes-singleton">
<section xml:id="beans-factory-scopes-singleton">
<title>The singleton scope</title>
<para>Only one <emphasis>shared</emphasis> instance of a singleton bean is
@@ -146,7 +150,7 @@
&lt;bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/&gt;</programlisting>
</section>
<section id="beans-factory-scopes-prototype">
<section xml:id="beans-factory-scopes-prototype">
<title>The prototype scope</title>
<para>The non-singleton, prototype scope of bean deployment results in the
@@ -175,7 +179,7 @@
<para>The following example defines a bean as a prototype in XML:</para>
<programlisting language="xml"><lineannotation>&lt;!-- using <literal>spring-beans-2.0.dtd</literal> --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- using spring-beans-2.0.dtd --&gt;</lineannotation>
&lt;bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/&gt;</programlisting>
<para>In contrast to the other scopes, Spring does not manage the complete
@@ -199,7 +203,7 @@
see <xref linkend="beans-factory-lifecycle"/>.)</para>
</section>
<section id="beans-factory-scopes-sing-prot-interaction">
<section xml:id="beans-factory-scopes-sing-prot-interaction">
<title>Singleton beans with prototype-bean dependencies</title>
<para>When you use singleton-scoped beans with dependencies on prototype
@@ -220,7 +224,7 @@
linkend="beans-factory-method-injection"/></para>
</section>
<section id="beans-factory-scopes-other">
<section xml:id="beans-factory-scopes-other">
<title>Request, session, and global session scopes</title>
<para>The <literal>request</literal>, <literal>session</literal>, and
@@ -233,7 +237,7 @@
<classname>IllegalStateException</classname> complaining about an unknown
bean scope.</para>
<section id="beans-factory-scopes-other-web-configuration">
<section xml:id="beans-factory-scopes-other-web-configuration">
<title>Initial web configuration</title>
<para>To support the scoping of beans at the <literal>request</literal>,
@@ -301,7 +305,7 @@
call chain.</para>
</section>
<section id="beans-factory-scopes-request">
<section xml:id="beans-factory-scopes-request">
<title>Request scope</title>
<para>Consider the following bean definition:</para>
@@ -320,7 +324,7 @@
is scoped to the request is discarded.</para>
</section>
<section id="beans-factory-scopes-session">
<section xml:id="beans-factory-scopes-session">
<title>Session scope</title>
<para>Consider the following bean definition:</para>
@@ -345,7 +349,7 @@
<interfacename>Session</interfacename> is also discarded.</para>
</section>
<section id="beans-factory-scopes-global-session">
<section xml:id="beans-factory-scopes-global-session">
<title>Global session scope</title>
<para>Consider the following bean definition:</para>
@@ -369,7 +373,7 @@
no error is raised.</para>
</section>
<section id="beans-factory-scopes-other-injection">
<section xml:id="beans-factory-scopes-other-injection">
<title>Scoped beans as dependencies</title>
<para>The Spring IoC container manages not only the instantiation of your
@@ -403,7 +407,7 @@
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
<lineannotation>&lt;!-- an HTTP <interfacename>Session</interfacename>-scoped bean exposed as a proxy --&gt;</lineannotation>
<lineannotation>&lt;!-- an HTTP Session-scoped bean exposed as a proxy --&gt;</lineannotation>
&lt;bean id="userPreferences" class="com.foo.UserPreferences" scope="session"&gt;
<lineannotation>&lt;!-- instructs the container to proxy the surrounding bean --&gt;</lineannotation>
@@ -413,7 +417,7 @@
<lineannotation>&lt;!-- a singleton-scoped bean injected with a proxy to the above bean --&gt;</lineannotation>
&lt;bean id="userService" class="com.foo.SimpleUserService"&gt;
<lineannotation>&lt;!-- a reference to the proxied <literal>userPreferences</literal> bean --&gt;</lineannotation>
<lineannotation>&lt;!-- a reference to the proxied userPreferences bean --&gt;</lineannotation>
&lt;property name="userPreferences" ref="userPreferences"/&gt;
&lt;/bean&gt;
@@ -493,7 +497,7 @@
&lt;property name="userPreferences" ref="userPreferences"/&gt;
&lt;/bean&gt;</programlisting>
<section id="beans-factory-scopes-other-injection-proxies">
<section xml:id="beans-factory-scopes-other-injection-proxies">
<title>Choosing the type of proxy to create</title>
<para>By default, when the Spring container creates a proxy for a bean
@@ -517,7 +521,7 @@
collaborators into which the scoped bean is injected must reference
the bean through one of its interfaces.</para>
<programlisting language="xml"><lineannotation>&lt;!-- <classname>DefaultUserPreferences</classname> implements the <interfacename>UserPreferences</interfacename> interface --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- DefaultUserPreferences implements the UserPreferences interface --&gt;</lineannotation>
&lt;bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session"&gt;
&lt;aop:scoped-proxy proxy-target-class="false"<literal/>/&gt;
&lt;/bean&gt;
@@ -532,7 +536,7 @@
</section>
</section>
<section id="beans-factory-scopes-custom">
<section xml:id="beans-factory-scopes-custom">
<title>Custom scopes</title>
<para>As of Spring 2.0, the bean scoping mechanism is extensible. You can
@@ -541,7 +545,7 @@
override the built-in <literal>singleton</literal> and
<literal>prototype</literal> scopes.</para>
<section id="beans-factory-scopes-custom-creating">
<section xml:id="beans-factory-scopes-custom-creating">
<title>Creating a custom scope</title>
<para>To integrate your custom scope(s) into the Spring container, you
@@ -550,9 +554,9 @@
interface, which is described in this section. For an idea of how to
implement your own scopes, see the <interfacename>Scope</interfacename>
implementations that are supplied with the Spring Framework itself and
the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/Scope.html"
>Scope Javadoc</ulink>, which explains the methods you need to implement
the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/Scope.html"
>Scope Javadoc</link>, which explains the methods you need to implement
in more detail.</para>
<para>The <literal>Scope</literal> interface has four methods to get
@@ -590,7 +594,7 @@
<programlisting language="java">String getConversationId()</programlisting>
</section>
<section id="beans-factory-scopes-custom-using">
<section xml:id="beans-factory-scopes-custom-using">
<title>Using a custom scope</title>
<para>After you write and test one or more custom

View File

@@ -1,21 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<section xml:id="beans-standard-annotations"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans-standard-annotations">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Using JSR 330 Standard Annotations</title>
<para>Starting with Spring 3.0, Spring offers support for JSR-330 standard annotations (Dependency Injection).
Those annotations are scanned in the same way as the Spring annotations. You just need to have the relevant jars in your classpath.
</para>
<note>
<para>
<para>
If you are using Maven, the <interfacename>javax.inject</interfacename> artifact is available
in the standard Maven repository
(<ulink url="http://repo1.maven.org/maven2/javax/inject/javax.inject/1/">http://repo1.maven.org/maven2/javax/inject/javax.inject/1/</ulink>).
(<link xl:href="http://repo1.maven.org/maven2/javax/inject/javax.inject/1/">http://repo1.maven.org/maven2/javax/inject/javax.inject/1/</link>).
You can add the following dependency to your file pom.xml:
</para>
</para>
<programlisting language="xml">
&lt;dependency&gt;
&lt;groupId&gt;javax.inject&lt;/groupId&gt;
@@ -23,8 +27,8 @@
&lt;version&gt;1&lt;/version&gt;
&lt;/dependency&gt;</programlisting>
</note>
<section id="beans-inject-named">
<section xml:id="beans-inject-named">
<title>Dependency Injection with <interfacename>@Inject</interfacename> and <interfacename>@Named</interfacename></title>
<para>Instead of <interfacename>@Autowired</interfacename>,
@@ -45,10 +49,10 @@ public class SimpleMovieLister {
</para>
<para>As with <interfacename>@Autowired</interfacename>, it is possible to use <interfacename>@Inject</interfacename>
at the class-level, field-level, method-level and constructor-argument level.
at the class-level, field-level, method-level and constructor-argument level.
If you would like to use a qualified name for the dependency that should be injected,
you should use the <interfacename>@Named</interfacename> annotation as follows:
If you would like to use a qualified name for the dependency that should be injected,
you should use the <interfacename>@Named</interfacename> annotation as follows:
<programlisting language="java">import javax.inject.Inject;
import javax.inject.Named;
@@ -62,18 +66,18 @@ public class SimpleMovieLister {
this.movieFinder = movieFinder;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
}</programlisting>
</para>
</section>
<section id="beans-named">
<section xml:id="beans-named">
<title><interfacename>@Named</interfacename>: a standard equivalent to the <interfacename>@Component</interfacename> annotation</title>
<para>
Instead of <interfacename>@Component</interfacename>, <interfacename>@javax.inject.Named</interfacename> may be used as follows:
<programlisting language="java">import javax.inject.Inject;
import javax.inject.Named;
@Named("movieListener")
public class SimpleMovieLister {
@@ -84,7 +88,7 @@ public class SimpleMovieLister {
this.movieFinder = movieFinder;
}
<lineannotation>// ...</lineannotation>
}</programlisting>
}</programlisting>
</para>
<para>
@@ -94,7 +98,7 @@ can be used in a similar fashion:
<programlisting language="java">import javax.inject.Inject;
import javax.inject.Named;
@Named
public class SimpleMovieLister {
@@ -114,17 +118,17 @@ component-scanning in the exact same way as when using Spring annotations:
<programlisting language="xml">&lt;beans&gt;
&lt;context:component-scan base-package="org.example"/&gt;
&lt;/beans&gt;</programlisting>
&lt;/beans&gt;</programlisting>
</para>
</section>
<section id="beans-standard-annotations-limitations">
<section xml:id="beans-standard-annotations-limitations">
<title>Limitations of the standard approach</title>
<para>When working with standard annotations, it is important to know that
some significant features are not available as shown in the table below:</para>
<para><table id="annotations-comparison">
<para>When working with standard annotations, it is important to know that
some significant features are not available as shown in the table below:</para>
<para><table xml:id="annotations-comparison">
<title>Spring annotations vs. standard annotations</title>
<tgroup cols="3">
@@ -156,46 +160,46 @@ component-scanning in the exact same way as when using Spring annotations:
<entry>@Scope("singleton")</entry>
<entry>@Singleton</entry>
<entry>
<para>
The JSR-330 default scope is like Spring's <interfacename>prototype</interfacename>.
However, in order to keep it consistent with Spring's general defaults,
a JSR-330 bean declared in the Spring container is a
<interfacename>singleton</interfacename> by default. In order to use a
scope other than <interfacename>singleton</interfacename>, you should use Spring's
<interfacename>@Scope</interfacename> annotation.
</para>
<para>
<interfacename>javax.inject</interfacename> also provides a
<ulink url="http://download.oracle.com/javaee/6/api/javax/inject/Scope.html">@Scope</ulink> annotation.
Nevertheless, this one is only intended to be used for creating your own annotations.
</para>
<para>
The JSR-330 default scope is like Spring's <interfacename>prototype</interfacename>.
However, in order to keep it consistent with Spring's general defaults,
a JSR-330 bean declared in the Spring container is a
<interfacename>singleton</interfacename> by default. In order to use a
scope other than <interfacename>singleton</interfacename>, you should use Spring's
<interfacename>@Scope</interfacename> annotation.
</para>
<para>
<interfacename>javax.inject</interfacename> also provides a
<link xl:href="http://download.oracle.com/javaee/6/api/javax/inject/Scope.html">@Scope</link> annotation.
Nevertheless, this one is only intended to be used for creating your own annotations.
</para>
</entry>
</row>
</row>
<row>
<entry>@Qualifier</entry>
<entry>@Named</entry>
<entry>&#151;</entry>
</row>
</row>
<row>
<entry>@Value</entry>
<entry>&#151;</entry>
<entry>no equivalent</entry>
</row>
</row>
<row>
<entry>@Required</entry>
<entry>&#151;</entry>
<entry>no equivalent</entry>
</row>
</row>
<row>
<entry>@Lazy</entry>
<entry>&#151;</entry>
<entry>no equivalent</entry>
</row>
</tbody>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
</section>
</section>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="beans"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="beans">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>The IoC container</title>
<section id="beans-introduction">
<section xml:id="beans-introduction">
<title>Introduction to the Spring IoC container and beans</title>
<para>This chapter covers the Spring Framework implementation of the
@@ -28,13 +32,13 @@ The footnote should x-ref to first section in that chapter but I can't find the
<para>The <literal>org.springframework.beans</literal> and
<literal>org.springframework.context</literal> packages are the basis for
Spring Framework's IoC container. The <interfacename><ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/BeanFactory.html"
>BeanFactory</ulink></interfacename> interface provides an advanced
Spring Framework's IoC container. The <interfacename><link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/BeanFactory.html"
>BeanFactory</link></interfacename> interface provides an advanced
configuration mechanism capable of managing any type of object.
<literal><ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/context/ApplicationContext.html"
>ApplicationContext</ulink></literal> is a sub-interface of
<literal><link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/context/ApplicationContext.html"
>ApplicationContext</link></literal> is a sub-interface of
<interfacename>BeanFactory.</interfacename> It adds easier integration
with Spring's AOP features; message resource handling (for use in
internationalization), event publication; and application-layer specific
@@ -63,7 +67,7 @@ The footnote should x-ref to first section in that chapter but I can't find the
container.</para>
</section>
<section id="beans-basics">
<section xml:id="beans-basics">
<title>Container overview</title>
<para>The interface
@@ -79,11 +83,11 @@ The footnote should x-ref to first section in that chapter but I can't find the
<para>Several implementations of the
<classname>ApplicationContext</classname> interface are supplied
out-of-the-box with Spring. In standalone applications it is common to
create an instance of <ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/context/support/ClassPathXmlApplicationContext.html"
><classname>ClassPathXmlApplicationContext</classname></ulink> or <ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/context/support/FileSystemXmlApplicationContext.html"
><classname>FileSystemXmlApplicationContext</classname></ulink>.
create an instance of <link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/context/support/ClassPathXmlApplicationContext.html"
><classname>ClassPathXmlApplicationContext</classname></link> or <link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/context/support/FileSystemXmlApplicationContext.html"
><classname>FileSystemXmlApplicationContext</classname></link>.
<!-- MLP: Beverly to review --> While XML has been the traditional format
for defining configuration metadata you can instruct the container to use
Java annotations or code as the metadata format by providing a small amount
@@ -95,9 +99,9 @@ The footnote should x-ref to first section in that chapter but I can't find the
in a web application scenario, a simple eight (or so) lines of boilerplate
J2EE web descriptor XML in the <literal>web.xml</literal> file of the
application will typically suffice (see <xref linkend="context-create"/>).
If you are using the <ulink url="http://www.springsource.com/produts/sts"
>SpringSource Tool Suite</ulink> Eclipse-powered development environment
or <ulink url="http://www.springsource.org/roo">Spring Roo</ulink> this
If you are using the <link xl:href="http://www.springsource.com/produts/sts"
>SpringSource Tool Suite</link> Eclipse-powered development environment
or <link xl:href="http://www.springsource.org/roo">Spring Roo</link> this
boilerplate configuration can be easily created with few mouse clicks or
keystrokes.</para>
@@ -115,7 +119,7 @@ The footnote should x-ref to first section in that chapter but I can't find the
<caption><para>The Spring IoC container</para></caption>
</mediaobject></para>
<section id="beans-factory-metadata">
<section xml:id="beans-factory-metadata">
<title>Configuration metadata</title>
<para>As the preceding diagram shows, the Spring IoC container consumes a
@@ -147,9 +151,9 @@ The footnote should x-ref to first section in that chapter but I can't find the
<listitem>
<para><link linkend="beans-java">Java-based configuration</link>:
Starting with Spring 3.0, many features provided by the <ulink
url="http://www.springsource.org/javaconfig">Spring JavaConfig
project</ulink> became part of the core Spring Framework. Thus you
Starting with Spring 3.0, many features provided by the <link
xl:href="http://www.springsource.org/javaconfig">Spring JavaConfig
project</link> became part of the core Spring Framework. Thus you
can define beans external to your application classes by using Java
rather than XML files. To use these new features, see the
<interfacename>@Configuration</interfacename>, <interfacename>@Bean,
@@ -207,7 +211,7 @@ The footnote should x-ref to first section in that chapter but I can't find the
for more information.</para>
</section>
<section id="beans-factory-instantiation">
<section xml:id="beans-factory-instantiation">
<title>Instantiating a container</title>
<para>Instantiating a Spring IoC container is straightforward. The
@@ -279,7 +283,7 @@ The footnote should x-ref to first section in that chapter but I can't find the
<para>In the preceding example, the service layer consists of the class
<classname>PetStoreServiceImpl</classname>, and two data access objects
of the type <classname>SqlMapAccountDao</classname> and SqlMapItemDao
are based on the <ulink url="http://ibatis.apache.org/">iBatis</ulink>
are based on the <link xl:href="http://ibatis.apache.org/">iBatis</link>
Object/Relational mapping framework. The <literal>property
name</literal> element refers to the name of the JavaBean property, and
the <literal>ref</literal> element refers to the name of another bean
@@ -288,7 +292,7 @@ The footnote should x-ref to first section in that chapter but I can't find the
object's dependencies, see <link linkend="beans-dependencies"
>Dependencies</link>.</para>
<section id="beans-factory-xml-import">
<section xml:id="beans-factory-xml-import">
<title>Composing XML-based configuration metadata</title>
<para>It can be useful to have bean definitions span multiple XML files.
@@ -350,7 +354,7 @@ The footnote should x-ref to first section in that chapter but I can't find the
</section>
</section>
<section id="beans-factory-client">
<section xml:id="beans-factory-client">
<title>Using the container</title>
<para>The <interfacename>ApplicationContext</interfacename> is the
@@ -385,7 +389,7 @@ List userList = service.getUsernameList();
</section>
</section>
<section id="beans-definition">
<section xml:id="beans-definition">
<title>Bean overview</title>
<para>A Spring IoC container manages one or more <emphasis>beans</emphasis>.
@@ -426,7 +430,7 @@ List userList = service.getUsernameList();
<para>This metadata translates to a set of properties that make up each bean
definition.</para>
<table id="beans-factory-bean-definition-tbl">
<table xml:id="beans-factory-bean-definition-tbl">
<title>The bean definition</title>
<tgroup cols="2">
@@ -522,7 +526,7 @@ List userList = service.getUsernameList();
applications work solely with beans defined through metadata bean
definitions.</para>
<section id="beans-beanname">
<section xml:id="beans-beanname">
<title>Naming beans</title>
<para>Every bean has one or more identifiers. These identifiers must be
@@ -548,7 +552,7 @@ List userList = service.getUsernameList();
<para>You are not required to supply a name or id for a bean. If no name
or id is supplied explicitly, the container generates a unique name for
that bean. However, if you want to refer to that bean by name, through
the use of the <literal>ref</literal> element or <link lang=""
the use of the <literal>ref</literal> element or <link
linkend="beans-servicelocator">Service Locator</link> style lookup,
you must provide a name. Motivations for not supplying a name are
related to using <link linkend="beans-inner-beans">inner beans</link>
@@ -570,7 +574,7 @@ List userList = service.getUsernameList();
applying advice to a set of beans related by name.</para>
</sidebar>
<section id="beans-beanname-alias">
<section xml:id="beans-beanname-alias">
<title>Aliasing a bean outside the bean definition</title>
<para>In a bean definition itself, you can supply more than one name for
@@ -617,7 +621,7 @@ List userList = service.getUsernameList();
</section>
</section>
<section id="beans-factory-class">
<section xml:id="beans-factory-class">
<title>Instantiating beans</title>
<para>A bean definition essentially is a recipe for creating one or more
@@ -675,7 +679,7 @@ List userList = service.getUsernameList();
to separate the inner class name from the outer class name.</para>
</sidebar>
<section id="beans-factory-class-ctor">
<section xml:id="beans-factory-class-ctor">
<title>Instantiation with a constructor</title>
<para>When you create a bean by the constructor approach, all normal
@@ -709,7 +713,7 @@ List userList = service.getUsernameList();
Dependencies</link>.</para>
</section>
<section id="beans-factory-class-static-factory-method">
<section xml:id="beans-factory-class-static-factory-method">
<title>Instantiation with a static factory method</title>
<para>When defining a bean that you create with a static factory method,
@@ -749,7 +753,7 @@ List userList = service.getUsernameList();
configuration in detail</link>.</para>
</section>
<section id="beans-factory-class-instance-factory-method">
<section xml:id="beans-factory-class-instance-factory-method">
<title>Instantiation using an instance factory method</title>
<para>Similar to instantiation through a <link
@@ -763,7 +767,7 @@ List userList = service.getUsernameList();
to be invoked to create the object. Set the name of the factory method
itself with the <literal>factory-method</literal> attribute.</para>
<programlisting language="xml"><lineannotation>&lt;!-- the factory bean, which contains a method called <methodname>createInstance()</methodname> --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- the factory bean, which contains a method called createInstance() --&gt;</lineannotation>
&lt;bean id="serviceLocator" class="examples.DefaultServiceLocator"&gt;
<lineannotation>&lt;!-- inject any dependencies required by this locator bean --&gt;</lineannotation>
&lt;/bean&gt;
@@ -835,15 +839,13 @@ List userList = service.getUsernameList();
</section>
</section>
<xi:include href="beans-dependencies.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="beans-dependencies.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="beans-scopes.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="beans-customizing.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="beans-customizing.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="beans-child-bean-definitions">
<section xml:id="beans-child-bean-definitions">
<title>Bean definition inheritance</title>
<para>A bean definition can contain a lot of configuration information,
@@ -909,7 +911,7 @@ List userList = service.getUsernameList();
&lt;bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
parent="inheritedTestBeanWithoutClass" init-method="initialize"&gt;
&lt;property name="name" value="override"/&gt;
<lineannotation>&lt;!-- age will inherit the value of <literal>1</literal> from the parent bean definition--&gt;</lineannotation>
<lineannotation>&lt;!-- age will inherit the value of 1 from the parent bean definition--&gt;</lineannotation>
&lt;/bean&gt;</programlisting>
<para>The parent bean cannot be instantiated on its own because it is
@@ -950,7 +952,7 @@ List userList = service.getUsernameList();
<xi:include href="beans-java.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="context-load-time-weaver">
<section xml:id="context-load-time-weaver">
<title>Registering a <interfacename>LoadTimeWeaver</interfacename></title>
<para>The <interfacename>LoadTimeWeaver</interfacename> is used by Spring to dynamically
@@ -986,7 +988,7 @@ public class AppConfig {
<xi:include href="beans-context-additional.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="beans-beanfactory">
<section xml:id="beans-beanfactory">
<title>The BeanFactory</title>
<para>The <classname>BeanFactory</classname> provides the underlying basis
@@ -1007,7 +1009,7 @@ public class AppConfig {
<interfacename>ApplicationContext</interfacename> and how one might access
the IoC container directly through a classic singleton lookup.</para>
<section id="context-introduction-ctx-vs-beanfactory">
<section xml:id="context-introduction-ctx-vs-beanfactory">
<title><interfacename>BeanFactory</interfacename> or
<interfacename>ApplicationContext</interfacename>?</title>
@@ -1037,7 +1039,7 @@ public class AppConfig {
<interfacename>ApplicationContext</interfacename> interfaces and
implementations.</para>
<table id="context-introduction-ctx-vs-beanfactory-feature-matrix"
<table xml:id="context-introduction-ctx-vs-beanfactory-feature-matrix"
pgwide="1">
<title>Feature Matrix</title>
@@ -1113,7 +1115,7 @@ public class AppConfig {
<programlisting language="java">ConfigurableBeanFactory factory = new XmlBeanFactory(...);
<lineannotation>// now register any needed <interfacename>BeanPostProcessor</interfacename> instances</lineannotation>
<lineannotation>// now register any needed BeanPostProcessor instances</lineannotation>
MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
factory.addBeanPostProcessor(postProcessor);
@@ -1126,7 +1128,7 @@ factory.addBeanPostProcessor(postProcessor);
<programlisting language="java">XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
<lineannotation>// bring in some property values from a <classname>Properties</classname> file</lineannotation>
<lineannotation>// bring in some property values from a Properties file</lineannotation>
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
@@ -1144,7 +1146,7 @@ cfg.postProcessBeanFactory(factory);</programlisting>
AOP.</para>
</section>
<section id="beans-servicelocator">
<section xml:id="beans-servicelocator">
<title>Glue code and the evil singleton</title>
<para>It is best to write most application code in a dependency-injection
@@ -1176,12 +1178,12 @@ cfg.postProcessBeanFactory(factory);</programlisting>
components, such as in an EJB 2.1 environment, or when you want to share
a single ApplicationContext as a parent to WebApplicationContexts across
WAR files. In this case you should look into using the utility class
<ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/context/access/ContextSingletonBeanFactoryLocator.html"
><classname>ContextSingletonBeanFactoryLocator</classname></ulink>
locator that is described in this <ulink
url="http://blog.springsource.com/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/"
>SpringSource team blog entry</ulink>.</para>
<link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/context/access/ContextSingletonBeanFactoryLocator.html"
><classname>ContextSingletonBeanFactoryLocator</classname></link>
locator that is described in this <link
xl:href="http://blog.springsource.com/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/"
>SpringSource team blog entry</link>.</para>
</section>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="cci"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="cci">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>JCA CCI</title>
<section id="cci-introduction">
<section xml:id="cci-introduction">
<title>Introduction</title>
<para>Java EE provides a specification to standardize access to enterprise
@@ -45,10 +49,10 @@
</note>
</section>
<section id="cci-config">
<section xml:id="cci-config">
<title>Configuring CCI</title>
<section id="cci-config-connector">
<section xml:id="cci-config-connector">
<title>Connector configuration</title>
<para>The base resource to use JCA CCI is the
@@ -90,7 +94,7 @@
</note>
</section>
<section id="cci-config-connectionfactory">
<section xml:id="cci-config-connectionfactory">
<title><interfacename>ConnectionFactory</interfacename> configuration in
Spring</title>
@@ -133,7 +137,7 @@
</note>
</section>
<section id="cci-config-cci-connections">
<section xml:id="cci-config-cci-connections">
<title>Configuring CCI connections</title>
<para>JCA CCI allow the developer to configure the connections to the
@@ -192,7 +196,7 @@
&lt;/bean&gt;</programlisting>
</section>
<section id="cci-config-single-connection">
<section xml:id="cci-config-single-connection">
<title>Using a single CCI connection</title>
<para>If you want to use a single CCI connection, Spring provides a
@@ -232,10 +236,10 @@
</section>
</section>
<section id="cci-using">
<section xml:id="cci-using">
<title>Using Spring's CCI access support</title>
<section id="cci-record-creator">
<section xml:id="cci-record-creator">
<title>Record conversion</title>
<para>One of the aims of the JCA CCI support is to provide convenient
@@ -299,7 +303,7 @@
}</programlisting>
</section>
<section id="cci-using-template">
<section xml:id="cci-using-template">
<title>The <classname>CciTemplate</classname></title>
<para>The <classname>CciTemplate</classname> is the central class of the
@@ -408,7 +412,7 @@
}</programlisting>
</section>
<section id="cci-using-dao">
<section xml:id="cci-using-dao">
<title>DAO support</title>
<para>Spring's CCI support provides a abstract class for DAOs,
@@ -433,7 +437,7 @@
}</programlisting>
</section>
<section id="automatic-output-generation">
<section xml:id="automatic-output-generation">
<title>Automatic output record generation</title>
<para>If the connector used only supports the
@@ -473,13 +477,13 @@
</note>
</section>
<section id="template-summary">
<section xml:id="template-summary">
<title>Summary</title>
<para>The following table summarizes the mechanisms of the
<classname>CciTemplate</classname> class and the corresponding methods
called on the CCI <interfacename>Interaction</interfacename>
interface:<table frame="all" id="cci-interaction-execute-methods">
interface:<table frame="all" xml:id="cci-interaction-execute-methods">
<title>Usage of <interfacename>Interaction</interfacename> execute
methods</title>
@@ -601,7 +605,7 @@
</table></para>
</section>
<section id="cci-straight">
<section xml:id="cci-straight">
<title>Using a CCI <interfacename>Connection</interfacename> and
<interfacename>Interaction</interfacename> directly</title>
@@ -646,7 +650,7 @@
</note>
</section>
<section id="cci-template-example">
<section xml:id="cci-template-example">
<title>Example for <classname>CciTemplate</classname> usage</title>
<para>In this section, the usage of the
@@ -700,7 +704,7 @@ interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);</progr
new ConnectionCallback() {
public Object doInConnection(Connection connection, ConnectionFactory factory)
throws ResourceException {
<lineannotation>// do something...</lineannotation>
}
});
@@ -771,7 +775,7 @@ interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);</progr
</section>
</section>
<section id="cci-object">
<section xml:id="cci-object">
<title>Modeling CCI access as operation objects</title>
<para>The <literal>org.springframework.jca.cci.object</literal> package
@@ -788,7 +792,7 @@ interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);</progr
<interfacename>RecordExtractor</interfacename> interfaces, reusing the
machinery of Spring's core CCI support.</para>
<section id="cci-object-mapping-record">
<section xml:id="cci-object-mapping-record">
<title><classname>MappingRecordOperation</classname></title>
<para><classname>MappingRecordOperation</classname> essentially performs
@@ -847,7 +851,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
...</programlisting>
</section>
<section id="cci-object-mapping-comm-area">
<section xml:id="cci-object-mapping-comm-area">
<title><classname>MappingCommAreaOperation</classname></title>
<para>Some connectors use records based on a COMMAREA which represents
@@ -872,7 +876,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
}</programlisting>
</section>
<section id="cci-automatic-record-gen">
<section xml:id="cci-automatic-record-gen">
<title>Automatic output record generation</title>
<para>As every <classname>MappingRecordOperation</classname> subclass is
@@ -883,13 +887,13 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
information, see <xref linkend="automatic-output-generation" />.</para>
</section>
<section id="cci-object-summary">
<section xml:id="cci-object-summary">
<title>Summary</title>
<para>The operation object approach uses records in the same manner as
the <classname>CciTemplate</classname> class.</para>
<table frame="all" id="cci-interaction-methods">
<table frame="all" xml:id="cci-interaction-methods">
<title>Usage of Interaction execute methods</title>
<tgroup cols="3">
@@ -931,7 +935,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
</table>
</section>
<section id="cci-objects-mappring-record-example">
<section xml:id="cci-objects-mappring-record-example">
<title>Example for <classname>MappingRecordOperation</classname>
usage</title>
@@ -1045,7 +1049,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
&lt;/bean&gt;</programlisting>
</section>
<section id="cci-objects-mapping-comm-area-example">
<section xml:id="cci-objects-mapping-comm-area-example">
<title>Example for <classname>MappingCommAreaOperation</classname>
usage</title>
@@ -1130,7 +1134,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
</section>
</section>
<section id="cci-tx">
<section xml:id="cci-tx">
<title>Transactions</title>
<para>JCA specifies several levels of transaction support for resource

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<appendix xml:id="classic-spring"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="classic-spring">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Classic Spring Usage</title>
<para>This appendix discusses some classic Spring usage patterns as a
@@ -11,20 +15,20 @@
the current recommended usage is covered in the respective sections of the
reference manual.</para>
<section id="classic-spring-orm">
<section xml:id="classic-spring-orm">
<title>Classic ORM usage</title>
<para>This section documents the classic usage patterns that you might
encounter in a legacy Spring application. For the currently recommended
usage patterns, please refer to the <xref linkend="orm" /> chapter.</para>
<section id="classic-spring-hibernate">
<section xml:id="classic-spring-hibernate">
<title>Hibernate</title>
<para>For the currently recommended usage patterns for Hibernate see
<xref linkend="orm-hibernate" /></para>
<section id="orm-hibernate-template">
<section xml:id="orm-hibernate-template">
<title>The <classname>HibernateTemplate</classname></title>
<para>The basic programming model for templating looks as follows, for
@@ -57,7 +61,7 @@
}
public Collection loadProductsByCategory(String category) throws DataAccessException {
return this.hibernateTemplate.find("from test.Product product where product.category=?", category);
return this.hibernateTemplate.find("from test.Product product where product.category=?", category);
}
}</programlisting>
@@ -117,7 +121,7 @@
}</programlisting>
</section>
<section id="orm-hibernate-daos">
<section xml:id="orm-hibernate-daos">
<title>Implementing Spring-based DAOs without callbacks</title>
<para>As alternative to using Spring's
@@ -170,13 +174,13 @@
</section>
</section>
<section id="classic-spring-jdo">
<section xml:id="classic-spring-jdo">
<title>JDO</title>
<para>For the currently recommended usage patterns for JDO see <xref
linkend="orm-jdo" /></para>
<section id="orm-jdo-template">
<section xml:id="orm-jdo-template">
<title><classname>JdoTemplate</classname> and
<classname>JdoDaoSupport</classname></title>
@@ -189,15 +193,15 @@
<classname>JdoTemplate</classname>:</para>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="myProductDao" class="product.ProductDaoImpl"&gt;
&lt;property name="persistenceManagerFactory" ref="myPmf"/&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<programlisting language="java">public class ProductDaoImpl implements ProductDao {
private JdoTemplate jdoTemplate;
public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
@@ -208,7 +212,7 @@
return (Collection) this.jdoTemplate.execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
Query query = pm.newQuery(Product.class, "category = pCategory");
query.declareParameters("String pCategory");
query.declareParameters("String pCategory");
List result = query.execute(category);
<lineannotation>// do some further stuff with the result list</lineannotation>
return result;
@@ -237,7 +241,7 @@
typical requirements:</para>
<programlisting language="java">public class ProductDaoImpl extends JdoDaoSupport implements ProductDao {
public Collection loadProductsByCategory(String category) throws DataAccessException {
return getJdoTemplate().find(
Product.class, "category = pCategory", "String category", new Object[] {category});
@@ -257,13 +261,13 @@
</section>
</section>
<section id="classic-spring-jpa">
<section xml:id="classic-spring-jpa">
<title>JPA</title>
<para>For the currently recommended usage patterns for JPA see <xref
linkend="orm-jpa" /></para>
<section id="orm-jpa-template">
<section xml:id="orm-jpa-template">
<title><classname>JpaTemplate</classname> and
<classname>JpaDaoSupport</classname></title>
@@ -282,7 +286,7 @@
&lt;/beans&gt;</programlisting>
<programlisting language="java">public class JpaProductDao implements ProductDao {
private JpaTemplate jpaTemplate;
public void setEntityManagerFactory(EntityManagerFactory emf) {
@@ -294,7 +298,7 @@
public Object doInJpa(EntityManager em) throws PersistenceException {
Query query = em.createQuery("from Product as p where p.category = :category");
query.setParameter("category", category);
List result = query.getResultList();
List result = query.getResultList();
<lineannotation>// do some further processing with the result list</lineannotation>
return result;
}
@@ -322,7 +326,7 @@
subclasses:</para>
<programlisting language="java">public class ProductDaoImpl extends JpaDaoSupport implements ProductDao {
public Collection loadProductsByCategory(String category) throws DataAccessException {
Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
params.put("category", category);
@@ -348,13 +352,13 @@
</section>
</section>
<section id="clasic-spring-mvc">
<section xml:id="clasic-spring-mvc">
<title>Classic Spring MVC</title>
<para>...</para>
</section>
<section id="classic-spring-jms">
<section xml:id="classic-spring-jms">
<title>JMS Usage</title>
<para>One of the benefits of Spring's JMS support is to shield the user
@@ -392,7 +396,7 @@
</note>
</sidebar>
<section id="classic-spring-jms-template">
<section xml:id="classic-spring-jms-template">
<title>JmsTemplate</title>
<para>Located in the package
@@ -407,7 +411,7 @@
that the point-to-point domain, Queues, will be used.</para>
</section>
<section id="classic-spring-aysnc-messages">
<section xml:id="classic-spring-aysnc-messages">
<title>Asynchronous Message Reception </title>
<para><link
@@ -423,7 +427,7 @@
rely only on the JMS 1.0.2 API. </para>
</section>
<section id="classic-spring-jms-connections">
<section xml:id="classic-spring-jms-connections">
<title>Connections</title>
<para>The <classname>ConnectionFactory</classname> interface is part of
@@ -441,7 +445,7 @@
<classname>javax.jmsTopicConnection</classname>.</para>
</section>
<section id="classic-spring-jms-tx-management">
<section xml:id="classic-spring-jms-tx-management">
<title>Transaction Management</title>
<para>In a JMS 1.0.2 environment the class

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="dao"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="dao">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>DAO support</title>
<section id="dao-introduction">
<section xml:id="dao-introduction">
<title>Introduction</title>
<para>The Data Access Object (DAO) support in Spring is aimed at making it
@@ -16,7 +20,7 @@
to each technology.</para>
</section>
<section id="dao-exceptions">
<section xml:id="dao-exceptions">
<title>Consistent exception hierarchy</title>
<para>Spring provides a convenient translation from technology-specific
@@ -71,7 +75,7 @@
</mediaobject>
</section>
<section id="dao-annotations">
<section xml:id="dao-annotations">
<title>Annotations used for configuring DAO or Repository classes</title>
<para>The best way to guarantee that your Data Access Objects (DAOs) or
@@ -104,7 +108,7 @@ public class JpaMovieFinder implements MovieFinder {
@PersistenceContext
private EntityManager entityManager;
// ...
}</programlisting>
@@ -116,12 +120,12 @@ public class JpaMovieFinder implements MovieFinder {
public class HibernateMovieFinder implements MovieFinder {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// ...
}</programlisting>
@@ -137,12 +141,12 @@ public class HibernateMovieFinder implements MovieFinder {
public class JdbcMovieFinder implements MovieFinder {
private JdbcTemplate jdbcTemplate;
@Autowired
public void init(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// ...
}</programlisting>

View File

@@ -1,62 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<appendix xml:id="springbeansdtd"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="springbeansdtd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title><literal>spring-beans-2.0.dtd</literal></title>
<para><programlisting language="xml">&lt;!--
Spring XML Beans DTD, version 2.0
Authors: Rod Johnson, Juergen Hoeller, Alef Arendsen, Colin Sampaleanu, Rob Harrop
Spring XML Beans DTD, version 2.0
Authors: Rod Johnson, Juergen Hoeller, Alef Arendsen, Colin Sampaleanu, Rob Harrop
This defines a simple and consistent way of creating a namespace
of JavaBeans objects, managed by a Spring BeanFactory, read by
XmlBeanDefinitionReader (with DefaultBeanDefinitionDocumentReader).
This defines a simple and consistent way of creating a namespace
of JavaBeans objects, managed by a Spring BeanFactory, read by
XmlBeanDefinitionReader (with DefaultBeanDefinitionDocumentReader).
This document type is used by most Spring functionality, including
web application contexts, which are based on bean factories.
This document type is used by most Spring functionality, including
web application contexts, which are based on bean factories.
Each "bean" element in this document defines a JavaBean.
Typically the bean class is specified, along with JavaBean properties
and/or constructor arguments.
Each "bean" element in this document defines a JavaBean.
Typically the bean class is specified, along with JavaBean properties
and/or constructor arguments.
A bean instance can be a "singleton" (shared instance) or a "prototype"
(independent instance). Further scopes can be provided by extended
bean factories, for example in a web environment.
A bean instance can be a "singleton" (shared instance) or a "prototype"
(independent instance). Further scopes can be provided by extended
bean factories, for example in a web environment.
References among beans are supported, that is, setting a JavaBean property
or a constructor argument to refer to another bean in the same factory
(or an ancestor factory).
References among beans are supported, that is, setting a JavaBean property
or a constructor argument to refer to another bean in the same factory
(or an ancestor factory).
As alternative to bean references, "inner bean definitions" can be used.
Singleton flags of such inner bean definitions are effectively ignored:
Inner beans are typically anonymous prototypes.
As alternative to bean references, "inner bean definitions" can be used.
Singleton flags of such inner bean definitions are effectively ignored:
Inner beans are typically anonymous prototypes.
There is also support for lists, sets, maps, and java.util.Properties
as bean property types or constructor argument types.
There is also support for lists, sets, maps, and java.util.Properties
as bean property types or constructor argument types.
For simple purposes, this DTD is sufficient. As of Spring 2.0,
XSD-based bean definitions are supported as more powerful alternative.
For simple purposes, this DTD is sufficient. As of Spring 2.0,
XSD-based bean definitions are supported as more powerful alternative.
XML documents that conform to this DTD should declare the following doctype:
XML documents that conform to this DTD should declare the following doctype:
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
-->
&lt;!--
The document root. A document can contain bean definitions only,
imports only, or a mixture of both (typically with imports first).
The document root. A document can contain bean definitions only,
imports only, or a mixture of both (typically with imports first).
-->
&lt;!ELEMENT beans (
description?,
(import | alias | bean)*
description?,
(import | alias | bean)*
)>
&lt;!--
Default values for all bean definitions. Can be overridden at
the "bean" level. See those attribute definitions for details.
Default values for all bean definitions. Can be overridden at
the "bean" level. See those attribute definitions for details.
-->
&lt;!ATTLIST beans default-lazy-init (true | false) "false">
&lt;!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no">
@@ -66,37 +70,37 @@
&lt;!ATTLIST beans default-merge (true | false) "false">
&lt;!--
Element containing informative text describing the purpose of the enclosing
element. Always optional.
Used primarily for user documentation of XML bean definition documents.
Element containing informative text describing the purpose of the enclosing
element. Always optional.
Used primarily for user documentation of XML bean definition documents.
-->
&lt;!ELEMENT description (#PCDATA)>
&lt;!--
Specifies an XML bean definition resource to import.
Specifies an XML bean definition resource to import.
-->
&lt;!ELEMENT import EMPTY>
&lt;!--
The relative resource location of the XML bean definition file to import,
for example "myImport.xml" or "includes/myImport.xml" or "../myImport.xml".
The relative resource location of the XML bean definition file to import,
for example "myImport.xml" or "includes/myImport.xml" or "../myImport.xml".
-->
&lt;!ATTLIST import resource CDATA #REQUIRED>
&lt;!--
Defines an alias for a bean, which can reside in a different definition file.
Defines an alias for a bean, which can reside in a different definition file.
-->
&lt;!ELEMENT alias EMPTY>
&lt;!--
The name of the bean to define an alias for.
The name of the bean to define an alias for.
-->
&lt;!ATTLIST alias name CDATA #REQUIRED>
&lt;!--
The alias name to define for the bean.
The alias name to define for the bean.
-->
&lt;!ATTLIST alias alias CDATA #REQUIRED>
@@ -116,97 +120,97 @@
&lt;!ATTLIST meta value CDATA #REQUIRED>
&lt;!--
Defines a single (usually named) bean.
Defines a single (usually named) bean.
A bean definition may contain nested tags for constructor arguments,
property values, lookup methods, and replaced methods. Mixing constructor
injection and setter injection on the same bean is explicitly supported.
A bean definition may contain nested tags for constructor arguments,
property values, lookup methods, and replaced methods. Mixing constructor
injection and setter injection on the same bean is explicitly supported.
-->
&lt;!ELEMENT bean (
description?,
(meta | constructor-arg | property | lookup-method | replaced-method)*
description?,
(meta | constructor-arg | property | lookup-method | replaced-method)*
)>
&lt;!--
Beans can be identified by an id, to enable reference checking.
Beans can be identified by an id, to enable reference checking.
There are constraints on a valid XML id: if you want to reference your bean
in Java code using a name that's illegal as an XML id, use the optional
"name" attribute. If neither is given, the bean class name is used as id
(with an appended counter like "#2" if there is already a bean with that name).
There are constraints on a valid XML id: if you want to reference your bean
in Java code using a name that's illegal as an XML id, use the optional
"name" attribute. If neither is given, the bean class name is used as id
(with an appended counter like "#2" if there is already a bean with that name).
-->
&lt;!ATTLIST bean id ID #IMPLIED>
&lt;!--
Optional. Can be used to create one or more aliases illegal in an id.
Multiple aliases can be separated by any number of spaces, commas, or
semi-colons (or indeed any mixture of the three).
Optional. Can be used to create one or more aliases illegal in an id.
Multiple aliases can be separated by any number of spaces, commas, or
semi-colons (or indeed any mixture of the three).
-->
&lt;!ATTLIST bean name CDATA #IMPLIED>
&lt;!--
Each bean definition must specify the fully qualified name of the class,
except if it pure serves as parent for child bean definitions.
Each bean definition must specify the fully qualified name of the class,
except if it pure serves as parent for child bean definitions.
-->
&lt;!ATTLIST bean class CDATA #IMPLIED>
&lt;!--
Optionally specify a parent bean definition.
Optionally specify a parent bean definition.
Will use the bean class of the parent if none specified, but can
also override it. In the latter case, the child bean class must be
compatible with the parent, i.e. accept the parent's property values
and constructor argument values, if any.
Will use the bean class of the parent if none specified, but can
also override it. In the latter case, the child bean class must be
compatible with the parent, i.e. accept the parent's property values
and constructor argument values, if any.
A child bean definition will inherit constructor argument values,
property values and method overrides from the parent, with the option
to add new values. If init method, destroy method, factory bean and/or factory
method are specified, they will override the corresponding parent settings.
A child bean definition will inherit constructor argument values,
property values and method overrides from the parent, with the option
to add new values. If init method, destroy method, factory bean and/or factory
method are specified, they will override the corresponding parent settings.
The remaining settings will always be taken from the child definition:
depends on, autowire mode, dependency check, scope, lazy init.
The remaining settings will always be taken from the child definition:
depends on, autowire mode, dependency check, scope, lazy init.
-->
&lt;!ATTLIST bean parent CDATA #IMPLIED>
&lt;!--
The scope of this bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean() with the id),
or "prototype" (independent instance resulting from each call to
getBean(). Default is "singleton".
The scope of this bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean() with the id),
or "prototype" (independent instance resulting from each call to
getBean(). Default is "singleton".
Singletons are most commonly used, and are ideal for multi-threaded
service objects. Further scopes, such as "request" or "session",
might be supported by extended bean factories (for example, in a
web environment).
Singletons are most commonly used, and are ideal for multi-threaded
service objects. Further scopes, such as "request" or "session",
might be supported by extended bean factories (for example, in a
web environment).
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Inner bean definitions inherit the singleton status of their containing
bean definition, unless explicitly specified: The inner bean will be a
singleton if the containing bean is a singleton, and a prototype if
the containing bean has any other scope.
Inner bean definitions inherit the singleton status of their containing
bean definition, unless explicitly specified: The inner bean will be a
singleton if the containing bean is a singleton, and a prototype if
the containing bean has any other scope.
-->
&lt;!ATTLIST bean scope CDATA #IMPLIED>
&lt;!--
Is this bean "abstract", i.e. not meant to be instantiated itself but
rather just serving as parent for concrete child bean definitions.
Default is "false". Specify "true" to tell the bean factory to not try to
instantiate that particular bean in any case.
Is this bean "abstract", i.e. not meant to be instantiated itself but
rather just serving as parent for concrete child bean definitions.
Default is "false". Specify "true" to tell the bean factory to not try to
instantiate that particular bean in any case.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per abstract bean definition.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per abstract bean definition.
-->
&lt;!ATTLIST bean abstract (true | false) #IMPLIED>
&lt;!--
If this bean should be lazily initialized.
If false, it will get instantiated on startup by bean factories
that perform eager initialization of singletons.
If this bean should be lazily initialized.
If false, it will get instantiated on startup by bean factories
that perform eager initialization of singletons.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
-->
&lt;!ATTLIST bean lazy-init (true | false | default) "default">
@@ -217,163 +221,163 @@
&lt;!ATTLIST bean autowire-candidate (true | false) #IMPLIED>
&lt;!--
Optional attribute controlling whether to "autowire" bean properties.
This is an automagical process in which bean references don't need to be coded
explicitly in the XML bean definition file, but Spring works out dependencies.
Optional attribute controlling whether to "autowire" bean properties.
This is an automagical process in which bean references don't need to be coded
explicitly in the XML bean definition file, but Spring works out dependencies.
There are 5 modes:
There are 5 modes:
1. "no"
The traditional Spring default. No automagical wiring. Bean references
must be defined in the XML file via the &lt;ref> element. We recommend this
in most cases as it makes documentation more explicit.
1. "no"
The traditional Spring default. No automagical wiring. Bean references
must be defined in the XML file via the &lt;ref> element. We recommend this
in most cases as it makes documentation more explicit.
2. "byName"
Autowiring by property name. If a bean of class Cat exposes a dog property,
Spring will try to set this to the value of the bean "dog" in the current factory.
If there is no matching bean by name, nothing special happens;
use dependency-check="objects" to raise an error in that case.
2. "byName"
Autowiring by property name. If a bean of class Cat exposes a dog property,
Spring will try to set this to the value of the bean "dog" in the current factory.
If there is no matching bean by name, nothing special happens;
use dependency-check="objects" to raise an error in that case.
3. "byType"
Autowiring if there is exactly one bean of the property type in the bean factory.
If there is more than one, a fatal error is raised, and you can't use byType
autowiring for that bean. If there is none, nothing special happens;
use dependency-check="objects" to raise an error in that case.
3. "byType"
Autowiring if there is exactly one bean of the property type in the bean factory.
If there is more than one, a fatal error is raised, and you can't use byType
autowiring for that bean. If there is none, nothing special happens;
use dependency-check="objects" to raise an error in that case.
4. "constructor"
Analogous to "byType" for constructor arguments. If there isn't exactly one bean
of the constructor argument type in the bean factory, a fatal error is raised.
4. "constructor"
Analogous to "byType" for constructor arguments. If there isn't exactly one bean
of the constructor argument type in the bean factory, a fatal error is raised.
5. "autodetect"
Chooses "constructor" or "byType" through introspection of the bean class.
If a default no-arg constructor is found, "byType" gets applied.
5. "autodetect"
Chooses "constructor" or "byType" through introspection of the bean class.
If a default no-arg constructor is found, "byType" gets applied.
The latter two are similar to PicoContainer and make bean factories simple to
configure for small namespaces, but doesn't work as well as standard Spring
behavior for bigger applications.
The latter two are similar to PicoContainer and make bean factories simple to
configure for small namespaces, but doesn't work as well as standard Spring
behavior for bigger applications.
Note that explicit dependencies, i.e. "property" and "constructor-arg" elements,
always override autowiring. Autowire behavior can be combined with dependency
checking, which will be performed after all autowiring has been completed.
Note that explicit dependencies, i.e. "property" and "constructor-arg" elements,
always override autowiring. Autowire behavior can be combined with dependency
checking, which will be performed after all autowiring has been completed.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
-->
&lt;!ATTLIST bean autowire (no | byName | byType | constructor | autodetect | default) "default">
&lt;!--
Optional attribute controlling whether to check whether all this
beans dependencies, expressed in its properties, are satisfied.
Default is no dependency checking.
Optional attribute controlling whether to check whether all this
beans dependencies, expressed in its properties, are satisfied.
Default is no dependency checking.
"simple" type dependency checking includes primitives and String;
"objects" includes collaborators (other beans in the factory);
"all" includes both types of dependency checking.
"simple" type dependency checking includes primitives and String;
"objects" includes collaborators (other beans in the factory);
"all" includes both types of dependency checking.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
-->
&lt;!ATTLIST bean dependency-check (none | objects | simple | all | default) "default">
&lt;!--
The names of the beans that this bean depends on being initialized.
The bean factory will guarantee that these beans get initialized before.
The names of the beans that this bean depends on being initialized.
The bean factory will guarantee that these beans get initialized before.
Note that dependencies are normally expressed through bean properties or
constructor arguments. This property should just be necessary for other kinds
of dependencies like statics (*ugh*) or database preparation on startup.
Note that dependencies are normally expressed through bean properties or
constructor arguments. This property should just be necessary for other kinds
of dependencies like statics (*ugh*) or database preparation on startup.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
-->
&lt;!ATTLIST bean depends-on CDATA #IMPLIED>
&lt;!--
Optional attribute for the name of the custom initialization method
to invoke after setting bean properties. The method must have no arguments,
but may throw any exception.
Optional attribute for the name of the custom initialization method
to invoke after setting bean properties. The method must have no arguments,
but may throw any exception.
-->
&lt;!ATTLIST bean init-method CDATA #IMPLIED>
&lt;!--
Optional attribute for the name of the custom destroy method to invoke
on bean factory shutdown. The method must have no arguments,
but may throw any exception.
Optional attribute for the name of the custom destroy method to invoke
on bean factory shutdown. The method must have no arguments,
but may throw any exception.
Note: Only invoked on beans whose lifecycle is under full control
of the factory - which is always the case for singletons, but not
guaranteed for any other scope.
Note: Only invoked on beans whose lifecycle is under full control
of the factory - which is always the case for singletons, but not
guaranteed for any other scope.
-->
&lt;!ATTLIST bean destroy-method CDATA #IMPLIED>
&lt;!--
Optional attribute specifying the name of a factory method to use to
create this object. Use constructor-arg elements to specify arguments
to the factory method, if it takes arguments. Autowiring does not apply
to factory methods.
Optional attribute specifying the name of a factory method to use to
create this object. Use constructor-arg elements to specify arguments
to the factory method, if it takes arguments. Autowiring does not apply
to factory methods.
If the "class" attribute is present, the factory method will be a static
method on the class specified by the "class" attribute on this bean
definition. Often this will be the same class as that of the constructed
object - for example, when the factory method is used as an alternative
to a constructor. However, it may be on a different class. In that case,
the created object will *not* be of the class specified in the "class"
attribute. This is analogous to FactoryBean behavior.
If the "class" attribute is present, the factory method will be a static
method on the class specified by the "class" attribute on this bean
definition. Often this will be the same class as that of the constructed
object - for example, when the factory method is used as an alternative
to a constructor. However, it may be on a different class. In that case,
the created object will *not* be of the class specified in the "class"
attribute. This is analogous to FactoryBean behavior.
If the "factory-bean" attribute is present, the "class" attribute is not
used, and the factory method will be an instance method on the object
returned from a getBean call with the specified bean name. The factory
bean may be defined as a singleton or a prototype.
If the "factory-bean" attribute is present, the "class" attribute is not
used, and the factory method will be an instance method on the object
returned from a getBean call with the specified bean name. The factory
bean may be defined as a singleton or a prototype.
The factory method can have any number of arguments. Autowiring is not
supported. Use indexed constructor-arg elements in conjunction with the
factory-method attribute.
The factory method can have any number of arguments. Autowiring is not
supported. Use indexed constructor-arg elements in conjunction with the
factory-method attribute.
Setter Injection can be used in conjunction with a factory method.
Method Injection cannot, as the factory method returns an instance,
which will be used when the container creates the bean.
Setter Injection can be used in conjunction with a factory method.
Method Injection cannot, as the factory method returns an instance,
which will be used when the container creates the bean.
-->
&lt;!ATTLIST bean factory-method CDATA #IMPLIED>
&lt;!--
Alternative to class attribute for factory-method usage.
If this is specified, no class attribute should be used.
This should be set to the name of a bean in the current or
ancestor factories that contains the relevant factory method.
This allows the factory itself to be configured using Dependency
Injection, and an instance (rather than static) method to be used.
Alternative to class attribute for factory-method usage.
If this is specified, no class attribute should be used.
This should be set to the name of a bean in the current or
ancestor factories that contains the relevant factory method.
This allows the factory itself to be configured using Dependency
Injection, and an instance (rather than static) method to be used.
-->
&lt;!ATTLIST bean factory-bean CDATA #IMPLIED>
&lt;!--
Bean definitions can specify zero or more constructor arguments.
This is an alternative to "autowire constructor".
Arguments correspond to either a specific index of the constructor argument
list or are supposed to be matched generically by type.
Bean definitions can specify zero or more constructor arguments.
This is an alternative to "autowire constructor".
Arguments correspond to either a specific index of the constructor argument
list or are supposed to be matched generically by type.
Note: A single generic argument value will just be used once, rather than
potentially matched multiple times (as of Spring 1.1).
Note: A single generic argument value will just be used once, rather than
potentially matched multiple times (as of Spring 1.1).
constructor-arg elements are also used in conjunction with the factory-method
element to construct beans using static or instance factory methods.
constructor-arg elements are also used in conjunction with the factory-method
element to construct beans using static or instance factory methods.
-->
&lt;!ELEMENT constructor-arg (
description?,
(bean | ref | idref | value | null | list | set | map | props)?
description?,
(bean | ref | idref | value | null | list | set | map | props)?
)>
&lt;!--
The constructor-arg tag can have an optional index attribute,
to specify the exact index in the constructor argument list. Only needed
to avoid ambiguities, e.g. in case of 2 arguments of the same type.
The constructor-arg tag can have an optional index attribute,
to specify the exact index in the constructor argument list. Only needed
to avoid ambiguities, e.g. in case of 2 arguments of the same type.
-->
&lt;!ATTLIST constructor-arg index CDATA #IMPLIED>
&lt;!--
The constructor-arg tag can have an optional type attribute,
to specify the exact type of the constructor argument. Only needed
to avoid ambiguities, e.g. in case of 2 single argument constructors
that can both be converted from a String.
The constructor-arg tag can have an optional type attribute,
to specify the exact type of the constructor argument. Only needed
to avoid ambiguities, e.g. in case of 2 single argument constructors
that can both be converted from a String.
-->
&lt;!ATTLIST constructor-arg type CDATA #IMPLIED>
@@ -389,20 +393,20 @@
&lt;!--
Bean definitions can have zero or more properties.
Property elements correspond to JavaBean setter methods exposed
by the bean classes. Spring supports primitives, references to other
beans in the same or related factories, lists, maps and properties.
Bean definitions can have zero or more properties.
Property elements correspond to JavaBean setter methods exposed
by the bean classes. Spring supports primitives, references to other
beans in the same or related factories, lists, maps and properties.
-->
&lt;!ELEMENT property (
description?, meta*,
(bean | ref | idref | value | null | list | set | map | props)?
description?, meta*,
(bean | ref | idref | value | null | list | set | map | props)?
)>
&lt;!--
The property name attribute is the name of the JavaBean property.
This follows JavaBean conventions: a name of "age" would correspond
to setAge()/optional getAge() methods.
The property name attribute is the name of the JavaBean property.
This follows JavaBean conventions: a name of "age" would correspond
to setAge()/optional getAge() methods.
-->
&lt;!ATTLIST property name CDATA #REQUIRED>
@@ -418,86 +422,86 @@
&lt;!--
A lookup method causes the IoC container to override the given method and return
the bean with the name given in the bean attribute. This is a form of Method Injection.
It's particularly useful as an alternative to implementing the BeanFactoryAware
interface, in order to be able to make getBean() calls for non-singleton instances
at runtime. In this case, Method Injection is a less invasive alternative.
A lookup method causes the IoC container to override the given method and return
the bean with the name given in the bean attribute. This is a form of Method Injection.
It's particularly useful as an alternative to implementing the BeanFactoryAware
interface, in order to be able to make getBean() calls for non-singleton instances
at runtime. In this case, Method Injection is a less invasive alternative.
-->
&lt;!ELEMENT lookup-method EMPTY>
&lt;!--
Name of a lookup method. This method should take no arguments.
Name of a lookup method. This method should take no arguments.
-->
&lt;!ATTLIST lookup-method name CDATA #IMPLIED>
&lt;!--
Name of the bean in the current or ancestor factories that the lookup method
should resolve to. Often this bean will be a prototype, in which case the
lookup method will return a distinct instance on every invocation. This
is useful for single-threaded objects.
Name of the bean in the current or ancestor factories that the lookup method
should resolve to. Often this bean will be a prototype, in which case the
lookup method will return a distinct instance on every invocation. This
is useful for single-threaded objects.
-->
&lt;!ATTLIST lookup-method bean CDATA #IMPLIED>
&lt;!--
Similar to the lookup method mechanism, the replaced-method element is used to control
IoC container method overriding: Method Injection. This mechanism allows the overriding
of a method with arbitrary code.
Similar to the lookup method mechanism, the replaced-method element is used to control
IoC container method overriding: Method Injection. This mechanism allows the overriding
of a method with arbitrary code.
-->
&lt;!ELEMENT replaced-method (
(arg-type)*
(arg-type)*
)>
&lt;!--
Name of the method whose implementation should be replaced by the IoC container.
If this method is not overloaded, there's no need to use arg-type subelements.
If this method is overloaded, arg-type subelements must be used for all
override definitions for the method.
Name of the method whose implementation should be replaced by the IoC container.
If this method is not overloaded, there's no need to use arg-type subelements.
If this method is overloaded, arg-type subelements must be used for all
override definitions for the method.
-->
&lt;!ATTLIST replaced-method name CDATA #IMPLIED>
&lt;!--
Bean name of an implementation of the MethodReplacer interface in the current
or ancestor factories. This may be a singleton or prototype bean. If it's
a prototype, a new instance will be used for each method replacement.
Singleton usage is the norm.
Bean name of an implementation of the MethodReplacer interface in the current
or ancestor factories. This may be a singleton or prototype bean. If it's
a prototype, a new instance will be used for each method replacement.
Singleton usage is the norm.
-->
&lt;!ATTLIST replaced-method replacer CDATA #IMPLIED>
&lt;!--
Subelement of replaced-method identifying an argument for a replaced method
in the event of method overloading.
Subelement of replaced-method identifying an argument for a replaced method
in the event of method overloading.
-->
&lt;!ELEMENT arg-type (#PCDATA)>
&lt;!--
Specification of the type of an overloaded method argument as a String.
For convenience, this may be a substring of the FQN. E.g. all the
following would match "java.lang.String":
- java.lang.String
- String
- Str
Specification of the type of an overloaded method argument as a String.
For convenience, this may be a substring of the FQN. E.g. all the
following would match "java.lang.String":
- java.lang.String
- String
- Str
As the number of arguments will be checked also, this convenience can often
be used to save typing.
As the number of arguments will be checked also, this convenience can often
be used to save typing.
-->
&lt;!ATTLIST arg-type match CDATA #IMPLIED>
&lt;!--
Defines a reference to another bean in this factory or an external
factory (parent or included factory).
Defines a reference to another bean in this factory or an external
factory (parent or included factory).
-->
&lt;!ELEMENT ref EMPTY>
&lt;!--
References must specify a name of the target bean.
The "bean" attribute can reference any name from any bean in the context,
to be checked at runtime.
Local references, using the "local" attribute, have to use bean ids;
they can be checked by this DTD, thus should be preferred for references
within the same bean factory XML file.
References must specify a name of the target bean.
The "bean" attribute can reference any name from any bean in the context,
to be checked at runtime.
Local references, using the "local" attribute, have to use bean ids;
they can be checked by this DTD, thus should be preferred for references
within the same bean factory XML file.
-->
&lt;!ATTLIST ref bean CDATA #IMPLIED>
&lt;!ATTLIST ref local IDREF #IMPLIED>
@@ -505,132 +509,132 @@
&lt;!--
Defines a string property value, which must also be the id of another
bean in this factory or an external factory (parent or included factory).
While a regular 'value' element could instead be used for the same effect,
using idref in this case allows validation of local bean ids by the XML
parser, and name completion by supporting tools.
Defines a string property value, which must also be the id of another
bean in this factory or an external factory (parent or included factory).
While a regular 'value' element could instead be used for the same effect,
using idref in this case allows validation of local bean ids by the XML
parser, and name completion by supporting tools.
-->
&lt;!ELEMENT idref EMPTY>
&lt;!--
ID refs must specify a name of the target bean.
The "bean" attribute can reference any name from any bean in the context,
potentially to be checked at runtime by bean factory implementations.
Local references, using the "local" attribute, have to use bean ids;
they can be checked by this DTD, thus should be preferred for references
within the same bean factory XML file.
ID refs must specify a name of the target bean.
The "bean" attribute can reference any name from any bean in the context,
potentially to be checked at runtime by bean factory implementations.
Local references, using the "local" attribute, have to use bean ids;
they can be checked by this DTD, thus should be preferred for references
within the same bean factory XML file.
-->
&lt;!ATTLIST idref bean CDATA #IMPLIED>
&lt;!ATTLIST idref local IDREF #IMPLIED>
&lt;!--
Contains a string representation of a property value.
The property may be a string, or may be converted to the required
type using the JavaBeans PropertyEditor machinery. This makes it
possible for application developers to write custom PropertyEditor
implementations that can convert strings to arbitrary target objects.
Contains a string representation of a property value.
The property may be a string, or may be converted to the required
type using the JavaBeans PropertyEditor machinery. This makes it
possible for application developers to write custom PropertyEditor
implementations that can convert strings to arbitrary target objects.
Note that this is recommended for simple objects only.
Configure more complex objects by populating JavaBean
properties with references to other beans.
Note that this is recommended for simple objects only.
Configure more complex objects by populating JavaBean
properties with references to other beans.
-->
&lt;!ELEMENT value (#PCDATA)>
&lt;!--
The value tag can have an optional type attribute, to specify the
exact type that the value should be converted to. Only needed
if the type of the target property or constructor argument is
too generic: for example, in case of a collection element.
The value tag can have an optional type attribute, to specify the
exact type that the value should be converted to. Only needed
if the type of the target property or constructor argument is
too generic: for example, in case of a collection element.
-->
&lt;!ATTLIST value type CDATA #IMPLIED>
&lt;!--
Denotes a Java null value. Necessary because an empty "value" tag
will resolve to an empty String, which will not be resolved to a
null value unless a special PropertyEditor does so.
Denotes a Java null value. Necessary because an empty "value" tag
will resolve to an empty String, which will not be resolved to a
null value unless a special PropertyEditor does so.
-->
&lt;!ELEMENT null (#PCDATA)>
&lt;!--
A list can contain multiple inner bean, ref, collection, or value elements.
Java lists are untyped, pending generics support in Java 1.5,
although references will be strongly typed.
A list can also map to an array type. The necessary conversion
is automatically performed by the BeanFactory.
A list can contain multiple inner bean, ref, collection, or value elements.
Java lists are untyped, pending generics support in Java 1.5,
although references will be strongly typed.
A list can also map to an array type. The necessary conversion
is automatically performed by the BeanFactory.
-->
&lt;!ELEMENT list (
(bean | ref | idref | value | null | list | set | map | props)*
(bean | ref | idref | value | null | list | set | map | props)*
)>
&lt;!--
Enable/disable merging for collections when using parent/child beans.
Enable/disable merging for collections when using parent/child beans.
-->
&lt;!ATTLIST list merge (true | false | default) "default">
&lt;!--
Specify the default Java type for nested values.
Specify the default Java type for nested values.
-->
&lt;!ATTLIST list value-type CDATA #IMPLIED>
&lt;!--
A set can contain multiple inner bean, ref, collection, or value elements.
Java sets are untyped, pending generics support in Java 1.5,
although references will be strongly typed.
A set can contain multiple inner bean, ref, collection, or value elements.
Java sets are untyped, pending generics support in Java 1.5,
although references will be strongly typed.
-->
&lt;!ELEMENT set (
(bean | ref | idref | value | null | list | set | map | props)*
(bean | ref | idref | value | null | list | set | map | props)*
)>
&lt;!--
Enable/disable merging for collections when using parent/child beans.
Enable/disable merging for collections when using parent/child beans.
-->
&lt;!ATTLIST set merge (true | false | default) "default">
&lt;!--
Specify the default Java type for nested values.
Specify the default Java type for nested values.
-->
&lt;!ATTLIST set value-type CDATA #IMPLIED>
&lt;!--
A Spring map is a mapping from a string key to object.
Maps may be empty.
A Spring map is a mapping from a string key to object.
Maps may be empty.
-->
&lt;!ELEMENT map (
(entry)*
(entry)*
)>
&lt;!--
Enable/disable merging for collections when using parent/child beans.
Enable/disable merging for collections when using parent/child beans.
-->
&lt;!ATTLIST map merge (true | false | default) "default">
&lt;!--
Specify the default Java type for nested entry keys.
Specify the default Java type for nested entry keys.
-->
&lt;!ATTLIST map key-type CDATA #IMPLIED>
&lt;!--
Specify the default Java type for nested entry values.
Specify the default Java type for nested entry values.
-->
&lt;!ATTLIST map value-type CDATA #IMPLIED>
&lt;!--
A map entry can be an inner bean, ref, value, or collection.
The key of the entry is given by the "key" attribute or child element.
A map entry can be an inner bean, ref, value, or collection.
The key of the entry is given by the "key" attribute or child element.
-->
&lt;!ELEMENT entry (
key?,
(bean | ref | idref | value | null | list | set | map | props)?
(bean | ref | idref | value | null | list | set | map | props)?
)>
&lt;!--
Each map element must specify its key as attribute or as child element.
A key attribute is always a String value.
Each map element must specify its key as attribute or as child element.
A key attribute is always a String value.
-->
&lt;!ATTLIST entry key CDATA #IMPLIED>
@@ -650,35 +654,35 @@
&lt;!ATTLIST entry value-ref CDATA #IMPLIED>
&lt;!--
A key element can contain an inner bean, ref, value, or collection.
A key element can contain an inner bean, ref, value, or collection.
-->
&lt;!ELEMENT key (
(bean | ref | idref | value | null | list | set | map | props)
(bean | ref | idref | value | null | list | set | map | props)
)>
&lt;!--
Props elements differ from map elements in that values must be strings.
Props may be empty.
Props elements differ from map elements in that values must be strings.
Props may be empty.
-->
&lt;!ELEMENT props (
(prop)*
(prop)*
)>
&lt;!--
Enable/disable merging for collections when using parent/child beans.
Enable/disable merging for collections when using parent/child beans.
-->
&lt;!ATTLIST props merge (true | false | default) "default">
&lt;!--
Element content is the string value of the property.
Note that whitespace is trimmed off to avoid unwanted whitespace
caused by typical XML formatting.
Element content is the string value of the property.
Note that whitespace is trimmed off to avoid unwanted whitespace
caused by typical XML formatting.
-->
&lt;!ELEMENT prop (#PCDATA)>
&lt;!--
Each property element must specify its key.
Each property element must specify its key.
-->
&lt;!ATTLIST prop key CDATA #REQUIRED></programlisting></para>
</appendix>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="dynamic-language"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="dynamic-language">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Dynamic language support</title>
<section id="dynamic-language-introduction">
<section xml:id="dynamic-language-introduction">
<title>Introduction</title>
<sidebar>
<title>Why only these languages?</title>
@@ -19,7 +23,7 @@
There is nothing stopping the inclusion of further languages though. If you want
to see support for &lt;<emphasis>insert your favourite dynamic language here</emphasis>&gt;,
you can always raise an issue on Spring's
<ulink url="http://opensource.atlassian.com/projects/spring/secure/Dashboard.jspa">JIRA</ulink>
<link xl:href="http://opensource.atlassian.com/projects/spring/secure/Dashboard.jspa">JIRA</link>
page (or implement such support yourself).
</para>
</sidebar>
@@ -51,7 +55,7 @@
</para>
</section>
<section id="dynamic-language-a-first-example">
<section xml:id="dynamic-language-a-first-example">
<title>A first example</title>
<para>
This bulk of this chapter is concerned with describing the dynamic language support
@@ -68,7 +72,7 @@
<interfacename>Messenger</interfacename> won't know that the underlying
implementation is a Groovy script.
</para>
<programlisting source="java"><![CDATA[package org.springframework.scripting;
<programlisting language="java"><![CDATA[package org.springframework.scripting;
public interface Messenger {
@@ -78,7 +82,7 @@ public interface Messenger {
Here is the definition of a class that has a dependency on the
<interfacename>Messenger</interfacename> interface.
</para>
<programlisting source="java"><![CDATA[package org.springframework.scripting;
<programlisting language="java"><![CDATA[package org.springframework.scripting;
public class DefaultBookingService implements BookingService {
@@ -94,7 +98,7 @@ public class DefaultBookingService implements BookingService {
}]]></programlisting>
<para>Here is an implementation of the <interfacename>Messenger</interfacename> interface
in Groovy.</para>
<programlisting source="java"><![CDATA[// from the file 'Messenger.groovy'
<programlisting language="java"><![CDATA[// from the file 'Messenger.groovy'
package org.springframework.scripting.groovy;
// import the Messenger interface (written in Java) that is to be implemented
@@ -129,12 +133,12 @@ class GroovyMessenger implements Messenger {
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
]]><lineannotation>&lt;!-- this is the bean definition for the Groovy-backed <interfacename>Messenger</interfacename> implementation --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- this is the bean definition for the Groovy-backed Messenger implementation --&gt;</lineannotation><![CDATA[
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
<lang:property name="message" value="I Can Do The Frug" />
</lang:groovy>
]]><lineannotation>&lt;!-- an otherwise normal bean that will be injected by the Groovy-backed <interfacename>Messenger</interfacename> --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger --&gt;</lineannotation><![CDATA[
<bean id="bookingService" class="x.y.DefaultBookingService">
<property name="messenger" ref="messenger" />
</bean>
@@ -156,7 +160,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
</para>
</section>
<section id="dynamic-language-beans">
<section xml:id="dynamic-language-beans">
<title>Defining beans that are backed by dynamic languages</title>
<para>
This section describes exactly how you define Spring managed beans in
@@ -171,7 +175,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
<xref linkend="dynamic-language-resources" /> at the end of this chapter.
</para>
<section id="dynamic-language-beans-concepts">
<section xml:id="dynamic-language-beans-concepts">
<title>Common concepts</title>
<para>The steps involved in using dynamic-language-backed beans are as follows:</para>
<orderedlist numeration="arabic">
@@ -205,7 +209,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
language source files.
</para>
<section id="dynamic-language-beans-concepts-xml-language-element">
<section xml:id="dynamic-language-beans-concepts-xml-language-element">
<title>The <literal>&lt;lang:language/&gt;</literal> element</title>
<sidebar>
<title>XML Schema</title>
@@ -252,7 +256,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
</para>
</section>
<section id="dynamic-language-refreshable-beans">
<section xml:id="dynamic-language-refreshable-beans">
<title>Refreshable beans</title>
<para>
One of the (if not <emphasis>the</emphasis>) most compelling value adds
@@ -322,7 +326,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
call is only there so that the execution of the program pauses while I (the author)
go off and edit the underlying dynamic language source file so that the refresh will
trigger on the dynamic-language-backed bean when the program resumes execution.</para>
<programlisting source="java"><![CDATA[import org.springframework.context.ApplicationContext;
<programlisting language="java"><![CDATA[import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scripting.Messenger;
@@ -347,7 +351,7 @@ public final class Boot {
<filename>Messenger.groovy</filename> source file when the execution of
the program is paused.
</para>
<programlisting source="java"><![CDATA[package org.springframework.scripting
<programlisting language="java"><![CDATA[package org.springframework.scripting
class GroovyMessenger implements Messenger {
@@ -396,7 +400,7 @@ class GroovyMessenger implements Messenger {
</para>
</section>
<section id="dynamic-language-beans-inline">
<section xml:id="dynamic-language-beans-inline">
<title>Inline dynamic language source files</title>
<para>
The dynamic language support can also cater for dynamic language
@@ -451,14 +455,14 @@ class RubyMessenger &lt; Messenger
def getMessage
@@message
end
end
</lang:inline-script>
<lang:property name="message" value="Hello World!" />
</lang:jruby>]]></programlisting>
</section>
<section id="dynamic-language-beans-ctor-injection">
<section xml:id="dynamic-language-beans-ctor-injection">
<title>Understanding Constructor Injection in the context of dynamic-language-backed beans</title>
<para>
There is one <emphasis>very</emphasis> important thing to be aware of
@@ -469,7 +473,7 @@ end
properties 100% clear, the following mixture of code and configuration
will <emphasis>not</emphasis> work.
</para>
<programlisting source="java"><![CDATA[// from the file 'Messenger.groovy'
<programlisting language="java"><![CDATA[// from the file 'Messenger.groovy'
package org.springframework.scripting.groovy;
import org.springframework.scripting.Messenger
@@ -490,11 +494,11 @@ class GroovyMessenger implements Messenger {
<programlisting language="xml"><![CDATA[<lang:groovy id="badMessenger"
script-source="classpath:Messenger.groovy">
]]>
<lineannotation>&lt;!-- this next constructor argument will *not* be injected into the <classname>GroovyMessenger</classname> --&gt;</lineannotation>
<lineannotation>&lt;!-- this next constructor argument will *not* be injected into the GroovyMessenger --&gt;</lineannotation>
<lineannotation>&lt;!-- in fact, this isn't even allowed according to the schema --&gt;</lineannotation><![CDATA[
<constructor-arg value="]]><lineannotation><emphasis role="bold">This will *not* work</emphasis></lineannotation><![CDATA[" />]]>
<lineannotation>&lt;!-- <emphasis role="bold">only</emphasis> property values are injected into the dynamic-language-backed object --&gt;</lineannotation><![CDATA[
<constructor-arg value="]]><lineannotation>This will *not* work</lineannotation><![CDATA[" />]]>
<lineannotation>&lt;!-- only property values are injected into the dynamic-language-backed object --&gt;</lineannotation><![CDATA[
<lang:property name="anotherMessage" value="Passed straight through to the dynamic-language-backed object" />
</lang>]]></programlisting>
@@ -507,7 +511,7 @@ class GroovyMessenger implements Messenger {
</section>
</section>
<section id="dynamic-language-beans-jruby">
<section xml:id="dynamic-language-beans-jruby">
<title>JRuby beans</title>
<sidebar>
@@ -523,9 +527,11 @@ class GroovyMessenger implements Messenger {
</itemizedlist>
</sidebar>
<para>From the JRuby homepage...</para>
<para>
<quote>
<emphasis>JRuby is an 100% pure-Java implementation of the Ruby programming language.</emphasis>
</quote>
</para>
<para>
In keeping with the Spring philosophy of offering choice, Spring's
dynamic language support also supports beans defined in the JRuby
@@ -550,13 +556,13 @@ class GroovyMessenger implements Messenger {
interface that was defined earlier in this chapter (for your convenience it
is repeated below).
</para>
<programlisting source="ruby"><![CDATA[package org.springframework.scripting;
<programlisting language="ruby"><![CDATA[package org.springframework.scripting;
public interface Messenger {
String getMessage();
}]]></programlisting>
<programlisting source="ruby"><![CDATA[require 'java'
<programlisting language="ruby"><![CDATA[require 'java'
class RubyMessenger
include org.springframework.scripting.Messenger
@@ -579,7 +585,7 @@ RubyMessenger.new]]></programlisting>
<programlisting language="xml"><![CDATA[<lang:jruby id="messageService"
script-interfaces="org.springframework.scripting.Messenger"
script-source="classpath:RubyMessenger.rb">
<lang:property name="message" value="Hello World!" />
</lang:jruby>]]></programlisting>
@@ -591,7 +597,7 @@ RubyMessenger.new]]></programlisting>
can achieve this by simply instantiating a new instance of your JRuby class on the last
line of the source file like so:
</para>
<programlisting source="ruby"><![CDATA[require 'java'
<programlisting language="ruby"><![CDATA[require 'java'
include_class 'org.springframework.scripting.Messenger'
@@ -614,7 +620,9 @@ RubyMessenger.new]]></programlisting>
and the following text is there in the corresponding stacktrace, this will hopefully
allow you to identify and then easily rectify the issue):
</para>
<para>
<computeroutput><![CDATA[org.springframework.scripting.ScriptCompilationException: Compilation of JRuby script returned '']]></computeroutput>
</para>
<para>
To rectify this, simply instantiate a new instance of whichever class
you want to expose as a JRuby-dynamic-language-backed bean (as shown above). Please
@@ -628,7 +636,7 @@ RubyMessenger.new]]></programlisting>
</para>
</section>
<section id="dynamic-language-beans-groovy">
<section xml:id="dynamic-language-beans-groovy">
<title>Groovy beans</title>
<sidebar>
<title>The Groovy library dependencies</title>
@@ -649,19 +657,21 @@ RubyMessenger.new]]></programlisting>
</itemizedlist>
</sidebar>
<para>From the Groovy homepage...</para>
<para>
<quote>
<emphasis>Groovy is an agile dynamic language for the Java 2 Platform that has
many of the features that people like so much in languages like Python, Ruby
and Smalltalk, making them available to Java developers using a Java-like syntax.
</emphasis>
</quote>
</para>
<para>
If you have read this chapter straight from the top, you will already have
<link linkend="dynamic-language-a-first-example">seen an example</link> of a
Groovy-dynamic-language-backed bean. Let's look at another example (again
using an example from the Spring test suite).
</para>
<programlisting source="java"><![CDATA[package org.springframework.scripting;
<programlisting language="java"><![CDATA[package org.springframework.scripting;
public interface Calculator {
@@ -671,7 +681,7 @@ public interface Calculator {
Here is an implementation of the <interfacename>Calculator</interfacename>
interface in Groovy.
</para>
<programlisting source="java"><lineannotation>// from the file 'calculator.groovy'</lineannotation><![CDATA[
<programlisting language="java"><lineannotation>// from the file 'calculator.groovy'</lineannotation><![CDATA[
package org.springframework.scripting.groovy
class GroovyCalculator implements Calculator {
@@ -687,7 +697,7 @@ class GroovyCalculator implements Calculator {
<para>
Lastly, here is a small application to exercise the above configuration.
</para>
<programlisting source="java"><![CDATA[package org.springframework.scripting;
<programlisting language="java"><![CDATA[package org.springframework.scripting;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -716,7 +726,7 @@ public class Main {
conventions of one (public) class per source file.
</para>
<section id="dynamic-language-beans-groovy-customizer">
<section xml:id="dynamic-language-beans-groovy-customizer">
<title>Customising Groovy objects via a callback</title>
<para>
The <interfacename>GroovyObjectCustomizer</interfacename>
@@ -726,7 +736,7 @@ public class Main {
any required initialization method(s), or set some default property
values, or specify a custom <classname>MetaClass</classname>.
</para>
<programlisting source="java"><![CDATA[public interface GroovyObjectCustomizer {
<programlisting language="java"><![CDATA[public interface GroovyObjectCustomizer {
void customize(GroovyObject goo);
}]]></programlisting>
@@ -740,7 +750,7 @@ public class Main {
folks will want to do with this callback, and you can see an example
of doing that below.
</para>
<programlisting source="java"><![CDATA[public final class SimpleMethodTracingCustomizer implements GroovyObjectCustomizer {
<programlisting language="java"><![CDATA[public final class SimpleMethodTracingCustomizer implements GroovyObjectCustomizer {
public void customize(GroovyObject goo) {
DelegatingMetaClass metaClass = new DelegatingMetaClass(goo.getMetaClass()) {
@@ -762,10 +772,10 @@ public class Main {
Actually making use of a <interfacename>GroovyObjectCustomizer</interfacename>
is easy if you are using the Spring 2.0 namespace support.
</para>
<programlisting language="xml"><lineannotation>&lt;!-- define the <interfacename>GroovyObjectCustomizer</interfacename> just like any other bean --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- define the GroovyObjectCustomizer just like any other bean --&gt;</lineannotation>
<![CDATA[<bean id="tracingCustomizer" class="example.SimpleMethodTracingCustomizer" />
]]><lineannotation>&lt;!-- ... and plug it into the desired Groovy bean via the '<literal>customizer-ref</literal>' attribute --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- ... and plug it into the desired Groovy bean via the 'customizer-ref' attribute --&gt;</lineannotation><![CDATA[
<lang:groovy id="calculator"
script-source="classpath:org/springframework/scripting/groovy/Calculator.groovy"
customizer-ref="tracingCustomizer" />]]></programlisting>
@@ -775,7 +785,7 @@ public class Main {
</para>
<programlisting language="xml"><![CDATA[<bean id="calculator" class="org.springframework.scripting.groovy.GroovyScriptFactory">
<constructor-arg value="classpath:org/springframework/scripting/groovy/Calculator.groovy"/>
]]><lineannotation>&lt;!-- define the <interfacename>GroovyObjectCustomizer</interfacename> (as an inner bean) --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- define the GroovyObjectCustomizer (as an inner bean) --&gt;</lineannotation><![CDATA[
<constructor-arg>
<bean id="tracingCustomizer" class="example.SimpleMethodTracingCustomizer" />
</constructor-arg>
@@ -785,7 +795,7 @@ public class Main {
</section>
</section>
<section id="dynamic-language-beans-bsh">
<section xml:id="dynamic-language-beans-bsh">
<title>BeanShell beans</title>
<sidebar>
<title>The BeanShell library dependencies</title>
@@ -800,6 +810,7 @@ public class Main {
</itemizedlist>
</sidebar>
<para>From the BeanShell homepage...</para>
<para>
<quote>
<emphasis>BeanShell is a small, free, embeddable Java source interpreter
with dynamic language features, written in Java. BeanShell dynamically
@@ -807,6 +818,7 @@ public class Main {
conveniences such as loose types, commands, and method closures like those
in Perl and JavaScript.</emphasis>
</quote>
</para>
<para>
In contrast to Groovy, BeanShell-backed bean definitions require some (small)
additional configuration. The implementation of the BeanShell dynamic language
@@ -825,7 +837,7 @@ public class Main {
that was defined earlier in this chapter (repeated below for your
convenience).
</para>
<programlisting source="java"><![CDATA[package org.springframework.scripting;
<programlisting language="java"><![CDATA[package org.springframework.scripting;
public interface Messenger {
@@ -833,7 +845,7 @@ public interface Messenger {
}]]></programlisting>
<para>Here is the BeanShell 'implementation' (the term is used loosely here) of the
<interfacename>Messenger</interfacename> interface.</para>
<programlisting source="java"><![CDATA[String message;
<programlisting language="java"><![CDATA[String message;
String getMessage() {
return message;
@@ -856,7 +868,7 @@ void setMessage(String aMessage) {
</section>
</section>
<section id="dynamic-language-scenarios">
<section xml:id="dynamic-language-scenarios">
<title>Scenarios</title>
<para>
The possible scenarios where defining Spring managed beans in a scripting
@@ -864,7 +876,7 @@ void setMessage(String aMessage) {
describes two possible use cases for the dynamic language support in Spring.
</para>
<section id="dynamic-language-scenarios-controllers">
<section xml:id="dynamic-language-scenarios-controllers">
<title>Scripted Spring MVC Controllers</title>
<para>
One group of classes that may benefit from using dynamic-language-backed
@@ -903,7 +915,7 @@ void setMessage(String aMessage) {
<interfacename>org.springframework.web.servlet.mvc.Controller</interfacename>
implemented using the Groovy dynamic language.
</para>
<programlisting source="java"><![CDATA[// from the file '/WEB-INF/groovy/FortuneController.groovy'
<programlisting language="java"><![CDATA[// from the file '/WEB-INF/groovy/FortuneController.groovy'
package org.springframework.showcase.fortune.web
import org.springframework.showcase.fortune.service.FortuneService
@@ -932,7 +944,7 @@ class FortuneController implements Controller {
]]></programlisting>
</section>
<section id="dynamic-language-scenarios-validators">
<section xml:id="dynamic-language-scenarios-validators">
<title>Scripted Validators</title>
<para>
Another area of application development with Spring that may benefit
@@ -952,7 +964,7 @@ class FortuneController implements Controller {
<para>
Please note that in order to effect the automatic 'pickup' of any changes
to dynamic-language-backed beans, you will have had to enable the
'refreshable beans' feature. See
'refreshable beans' feature. See
<xref linkend="dynamic-language-refreshable-beans"/> for a full and
detailed treatment of this feature.
</para>
@@ -963,7 +975,7 @@ class FortuneController implements Controller {
implemented using the Groovy dynamic language. (See <xref linkend="validator"/>
for a discussion of the <interfacename>Validator</interfacename> interface.)
</para>
<programlisting source="java"><![CDATA[import org.springframework.validation.Validator
<programlisting language="java"><![CDATA[import org.springframework.validation.Validator
import org.springframework.validation.Errors
import org.springframework.beans.TestBean
@@ -972,7 +984,7 @@ class TestBeanValidator implements Validator {
boolean supports(Class clazz) {
return TestBean.class.isAssignableFrom(clazz)
}
void validate(Object bean, Errors errors) {
if(bean.name?.trim()?.size() > 0) {
return
@@ -983,14 +995,14 @@ class TestBeanValidator implements Validator {
</section>
</section>
<section id="dynamic-language-final-notes">
<section xml:id="dynamic-language-final-notes">
<title>Bits and bobs</title>
<para>
This last section contains some bits and bobs related to the dynamic language
support.
</para>
<section id="dynamic-language-final-notes-aop">
<section xml:id="dynamic-language-final-notes-aop">
<title>AOP - advising scripted beans</title>
<para>
It is possible to use the Spring AOP framework to advise scripted beans.
@@ -1009,7 +1021,7 @@ class TestBeanValidator implements Validator {
</para>
</section>
<section id="dynamic-language-final-notes-scopes">
<section xml:id="dynamic-language-final-notes-scopes">
<title>Scoping</title>
<para>
In case it is not immediately obvious, scripted beans can of course be scoped
@@ -1032,7 +1044,7 @@ class TestBeanValidator implements Validator {
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy" ]]><lineannotation><emphasis role="bold">scope="prototype"</emphasis></lineannotation><![CDATA[>
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy" ]]><lineannotation>scope="prototype"</lineannotation><![CDATA[>
<lang:property name="message" value="I Can Do The RoboCop" />
</lang:groovy>
@@ -1048,7 +1060,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
</section>
</section>
<section id="dynamic-language-resources">
<section xml:id="dynamic-language-resources">
<title>Further Resources</title>
<para>
Find below links to further resources about the various dynamic languages described
@@ -1056,13 +1068,13 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
</para>
<itemizedlist>
<listitem>
<para>The <ulink url="http://jruby.codehaus.org/">JRuby</ulink> homepage</para>
<para>The <link xl:href="http://jruby.codehaus.org/">JRuby</link> homepage</para>
</listitem>
<listitem>
<para>The <ulink url="http://groovy.codehaus.org/">Groovy</ulink> homepage</para>
<para>The <link xl:href="http://groovy.codehaus.org/">Groovy</link> homepage</para>
</listitem>
<listitem>
<para>The <ulink url="http://www.beanshell.org/">BeanShell</ulink> homepage</para>
<para>The <link xl:href="http://www.beanshell.org/">BeanShell</link> homepage</para>
</listitem>
</itemizedlist>
<para>
@@ -1071,7 +1083,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
chapter. While it is possible that such third party contributions may be added to the
list of languages supported by the main Spring distribution, your best bet for seeing
if your favourite scripting language is supported is the
<ulink url="https://springmodules.dev.java.net/">Spring Modules project</ulink>.
<link xl:href="https://springmodules.dev.java.net/">Spring Modules project</link>.
</para>
</section>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="ejb"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="ejb">
<title>Enterprise JavaBeans (EJB) integration</title>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Enterprise JavaBeans (EJB) integration</title>
<section id="ejb-introduction">
<section xml:id="ejb-introduction">
<title>Introduction</title>
<para>
As a lightweight container, Spring is often considered an EJB
@@ -29,100 +33,100 @@
implement EJBs. Spring provides particular value when accessing stateless
session beans (SLSBs), so we'll begin by discussing this.
</para>
</section>
</section>
<section id="ejb-access">
<title>Accessing EJBs</title>
<section xml:id="ejb-access">
<title>Accessing EJBs</title>
<section id="ejb-access-concepts">
<title>Concepts</title>
<para>
To invoke a method on a local or remote stateless session bean,
client code must normally perform a JNDI lookup to obtain the (local or
remote) EJB Home object, then use a 'create' method call on that object
to obtain the actual (local or remote) EJB object. One or more methods
are then invoked on the EJB.
<section xml:id="ejb-access-concepts">
<title>Concepts</title>
<para>
To invoke a method on a local or remote stateless session bean,
client code must normally perform a JNDI lookup to obtain the (local or
remote) EJB Home object, then use a 'create' method call on that object
to obtain the actual (local or remote) EJB object. One or more methods
are then invoked on the EJB.
</para>
<para>
To avoid repeated low-level code, many EJB applications use the
Service Locator and Business Delegate patterns. These are better than
spraying JNDI lookups throughout client code, but their usual
implementations have significant disadvantages. For example:
<para>
To avoid repeated low-level code, many EJB applications use the
Service Locator and Business Delegate patterns. These are better than
spraying JNDI lookups throughout client code, but their usual
implementations have significant disadvantages. For example:
</para>
<itemizedlist>
<listitem>
<para>
Typically code using EJBs depends on Service Locator or
Business Delegate singletons, making it hard to test.
</para>
</listitem>
<listitem>
<para>
In the case of the Service Locator pattern used without a
Business Delegate, application code still ends up having to invoke
the create() method on an EJB home, and deal with the resulting
exceptions. Thus it remains tied to the EJB API and the complexity
of the EJB programming model.
</para>
</listitem>
<listitem>
<para>
Implementing the Business Delegate pattern typically results
in significant code duplication, where we have to write numerous
methods that simply call the same method on the EJB.
</para>
</listitem>
</itemizedlist>
<para>
The Spring approach is to allow the creation and use of proxy objects,
normally configured inside a Spring container, which act as codeless
business delegates. You do not need to write another Service Locator, another
JNDI lookup, or duplicate methods in a hand-coded Business Delegate unless
you are actually adding real value in such code.
</para>
</section>
<itemizedlist>
<listitem>
<para>
Typically code using EJBs depends on Service Locator or
Business Delegate singletons, making it hard to test.
</para>
</listitem>
<listitem>
<para>
In the case of the Service Locator pattern used without a
Business Delegate, application code still ends up having to invoke
the create() method on an EJB home, and deal with the resulting
exceptions. Thus it remains tied to the EJB API and the complexity
of the EJB programming model.
</para>
</listitem>
<listitem>
<para>
Implementing the Business Delegate pattern typically results
in significant code duplication, where we have to write numerous
methods that simply call the same method on the EJB.
</para>
</listitem>
</itemizedlist>
<para>
The Spring approach is to allow the creation and use of proxy objects,
normally configured inside a Spring container, which act as codeless
business delegates. You do not need to write another Service Locator, another
JNDI lookup, or duplicate methods in a hand-coded Business Delegate unless
you are actually adding real value in such code.
</para>
</section>
<section id="ejb-access-local">
<title>Accessing local SLSBs</title>
<para>
Assume that we have a web controller that needs to use a local
EJB. Well follow best practice and use the EJB Business Methods
Interface pattern, so that the EJBs local interface extends a non
EJB-specific business methods interface. Lets call this business
methods interface <classname>MyComponent</classname>.
</para>
<programlisting language="java"><![CDATA[public interface MyComponent {
<section xml:id="ejb-access-local">
<title>Accessing local SLSBs</title>
<para>
Assume that we have a web controller that needs to use a local
EJB. Well follow best practice and use the EJB Business Methods
Interface pattern, so that the EJBs local interface extends a non
EJB-specific business methods interface. Lets call this business
methods interface <classname>MyComponent</classname>.
</para>
<programlisting language="java"><![CDATA[public interface MyComponent {
...
}]]></programlisting>
<para>
One of the main reasons to use the Business Methods Interface pattern
is to ensure that synchronization between method signatures in local
interface and bean implementation class is automatic. Another reason is
that it later makes it much easier for us to switch to a POJO (plain old
Java object) implementation of the service if it makes sense to do so.
Of course well also need to implement the local home interface and
provide an implementation class that implements <classname>SessionBean</classname>
and the <classname>MyComponent</classname> business methods interface. Now the
only Java coding well need to do to hook up our web tier controller to the
EJB implementation is to expose a setter method of type <classname>MyComponent</classname>
on the controller. This will save the reference as an instance variable in the
controller:
</para>
<programlisting language="java"><![CDATA[private MyComponent myComponent;
<para>
One of the main reasons to use the Business Methods Interface pattern
is to ensure that synchronization between method signatures in local
interface and bean implementation class is automatic. Another reason is
that it later makes it much easier for us to switch to a POJO (plain old
Java object) implementation of the service if it makes sense to do so.
Of course well also need to implement the local home interface and
provide an implementation class that implements <classname>SessionBean</classname>
and the <classname>MyComponent</classname> business methods interface. Now the
only Java coding well need to do to hook up our web tier controller to the
EJB implementation is to expose a setter method of type <classname>MyComponent</classname>
on the controller. This will save the reference as an instance variable in the
controller:
</para>
<programlisting language="java"><![CDATA[private MyComponent myComponent;
public void setMyComponent(MyComponent myComponent) {
this.myComponent = myComponent;
}]]></programlisting>
<para>
We can subsequently use this instance variable in any business
method in the controller. Now assuming we are obtaining our controller
object out of a Spring container, we can (in the same context) configure a
<classname>LocalStatelessSessionProxyFactoryBean</classname> instance, which
will be the EJB proxy object. The configuration of the proxy, and setting of
the <literal>myComponent</literal> property of the controller is done
with a configuration entry such as:
</para>
<programlisting language="xml"><![CDATA[<bean id="myComponent"
<para>
We can subsequently use this instance variable in any business
method in the controller. Now assuming we are obtaining our controller
object out of a Spring container, we can (in the same context) configure a
<classname>LocalStatelessSessionProxyFactoryBean</classname> instance, which
will be the EJB proxy object. The configuration of the proxy, and setting of
the <literal>myComponent</literal> property of the controller is done
with a configuration entry such as:
</para>
<programlisting language="xml"><![CDATA[<bean id="myComponent"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/myBean"/>
<property name="businessInterface" value="com.mycom.MyComponent"/>
@@ -131,21 +135,21 @@ public void setMyComponent(MyComponent myComponent) {
<bean id="myController" class="com.mycom.myController">
<property name="myComponent" ref="myComponent"/>
</bean>]]></programlisting>
<para>
Theres a lot of work happening behind the scenes, courtesy of
the Spring AOP framework, although you arent forced to work with AOP
concepts to enjoy the results. The <literal>myComponent</literal> bean
definition creates a proxy for the EJB, which implements the business
method interface. The EJB local home is cached on startup, so theres
only a single JNDI lookup. Each time the EJB is invoked, the proxy
invokes the <literal>classname</literal> method on the local EJB and
invokes the corresponding business method on the EJB.
</para>
<para>
The <literal>myController</literal> bean definition sets the
<literal>myComponent</literal> property of the controller class to the
EJB proxy.
</para>
<para>
Theres a lot of work happening behind the scenes, courtesy of
the Spring AOP framework, although you arent forced to work with AOP
concepts to enjoy the results. The <literal>myComponent</literal> bean
definition creates a proxy for the EJB, which implements the business
method interface. The EJB local home is cached on startup, so theres
only a single JNDI lookup. Each time the EJB is invoked, the proxy
invokes the <literal>classname</literal> method on the local EJB and
invokes the corresponding business method on the EJB.
</para>
<para>
The <literal>myController</literal> bean definition sets the
<literal>myComponent</literal> property of the controller class to the
EJB proxy.
</para>
<para>
Alternatively (and preferably in case of many such proxy definitions),
consider using the <literal>&lt;jee:local-slsb&gt;</literal>
@@ -157,87 +161,87 @@ public void setMyComponent(MyComponent myComponent) {
<bean id="myController" class="com.mycom.myController">
<property name="myComponent" ref="myComponent"/>
</bean>]]></programlisting>
<para>
This EJB access mechanism delivers huge simplification of
application code: the web tier code (or other EJB client code) has no
dependence on the use of EJB. If we want to replace this EJB reference
with a POJO or a mock object or other test stub, we could simply change
the <literal>myComponent</literal> bean definition without changing a
line of Java code. Additionally, we havent had to write a single line of
JNDI lookup or other EJB plumbing code as part of our application.
</para>
<para>
Benchmarks and experience in real applications indicate that the
performance overhead of this approach (which involves reflective
invocation of the target EJB) is minimal, and is typically undetectable
in typical use. Remember that we dont want to make fine-grained calls
to EJBs anyway, as theres a cost associated with the EJB infrastructure
in the application server.
</para>
<para>
There is one caveat with regards to the JNDI lookup. In a bean
container, this class is normally best used as a singleton (there simply
is no reason to make it a prototype). However, if that bean container
pre-instantiates singletons (as do the various XML
<classname>ApplicationContext</classname> variants)
you may have a problem if the bean container is loaded before the EJB
container loads the target EJB. That is because the JNDI lookup will be
performed in the <literal>init()</literal> method of this class and then
cached, but the EJB will not have been bound at the target location yet.
The solution is to not pre-instantiate this factory object, but allow it
to be created on first use. In the XML containers, this is controlled via
the <literal>lazy-init</literal> attribute.
</para>
<para>
Although this will not be of interest to the majority of Spring
users, those doing programmatic AOP work with EJBs may want to look at
<classname>LocalSlsbInvokerInterceptor</classname>.
</para>
</section>
<para>
This EJB access mechanism delivers huge simplification of
application code: the web tier code (or other EJB client code) has no
dependence on the use of EJB. If we want to replace this EJB reference
with a POJO or a mock object or other test stub, we could simply change
the <literal>myComponent</literal> bean definition without changing a
line of Java code. Additionally, we havent had to write a single line of
JNDI lookup or other EJB plumbing code as part of our application.
</para>
<para>
Benchmarks and experience in real applications indicate that the
performance overhead of this approach (which involves reflective
invocation of the target EJB) is minimal, and is typically undetectable
in typical use. Remember that we dont want to make fine-grained calls
to EJBs anyway, as theres a cost associated with the EJB infrastructure
in the application server.
</para>
<para>
There is one caveat with regards to the JNDI lookup. In a bean
container, this class is normally best used as a singleton (there simply
is no reason to make it a prototype). However, if that bean container
pre-instantiates singletons (as do the various XML
<classname>ApplicationContext</classname> variants)
you may have a problem if the bean container is loaded before the EJB
container loads the target EJB. That is because the JNDI lookup will be
performed in the <literal>init()</literal> method of this class and then
cached, but the EJB will not have been bound at the target location yet.
The solution is to not pre-instantiate this factory object, but allow it
to be created on first use. In the XML containers, this is controlled via
the <literal>lazy-init</literal> attribute.
</para>
<para>
Although this will not be of interest to the majority of Spring
users, those doing programmatic AOP work with EJBs may want to look at
<classname>LocalSlsbInvokerInterceptor</classname>.
</para>
</section>
<section id="ejb-access-remote">
<title>Accessing remote SLSBs</title>
<para>
Accessing remote EJBs is essentially identical to accessing local
EJBs, except that the
<classname>SimpleRemoteStatelessSessionProxyFactoryBean</classname> or
<section xml:id="ejb-access-remote">
<title>Accessing remote SLSBs</title>
<para>
Accessing remote EJBs is essentially identical to accessing local
EJBs, except that the
<classname>SimpleRemoteStatelessSessionProxyFactoryBean</classname> or
<literal>&lt;jee:remote-slsb&gt;</literal> configuration element is used.
Of course, with or without Spring, remote invocation semantics apply; a
call to a method on an object in another VM in another computer does
sometimes have to be treated differently in terms of usage scenarios and
failure handling.
</para>
<para>
Spring's EJB client support adds one more advantage over the
non-Spring approach. Normally it is problematic for EJB client code to
be easily switched back and forth between calling EJBs locally or
remotely. This is because the remote interface methods must declare that
they throw <classname>RemoteException</classname>, and client code must deal
with this, while the local interface methods don't. Client code
written for local EJBs which needs to be moved to remote EJBs
typically has to be modified to add handling for the remote exceptions,
and client code written for remote EJBs which needs to be moved to local
EJBs, can either stay the same but do a lot of unnecessary handling of
remote exceptions, or needs to be modified to remove that code. With the
Spring remote EJB proxy, you can instead not declare any thrown
<classname>RemoteException</classname> in your Business Method Interface and
implementing EJB code, have a remote interface which is identical except
that it does throw <classname>RemoteException</classname>, and rely on the
proxy to dynamically treat the two interfaces as if they were the same.
That is, client code does not have to deal with the checked
<classname>RemoteException</classname> class. Any actual
<classname>RemoteException</classname> that is thrown during the EJB
invocation will be re-thrown as the non-checked
<classname>RemoteAccessException</classname> class, which is a subclass of
<classname>RuntimeException</classname>. The target service can then be
switched at will between a local EJB or remote EJB (or even plain Java
object) implementation, without the client code knowing or caring. Of
course, this is optional; there is nothing stopping you from declaring
<classname>RemoteExceptions</classname> in your business interface.
</para>
</section>
Of course, with or without Spring, remote invocation semantics apply; a
call to a method on an object in another VM in another computer does
sometimes have to be treated differently in terms of usage scenarios and
failure handling.
</para>
<para>
Spring's EJB client support adds one more advantage over the
non-Spring approach. Normally it is problematic for EJB client code to
be easily switched back and forth between calling EJBs locally or
remotely. This is because the remote interface methods must declare that
they throw <classname>RemoteException</classname>, and client code must deal
with this, while the local interface methods don't. Client code
written for local EJBs which needs to be moved to remote EJBs
typically has to be modified to add handling for the remote exceptions,
and client code written for remote EJBs which needs to be moved to local
EJBs, can either stay the same but do a lot of unnecessary handling of
remote exceptions, or needs to be modified to remove that code. With the
Spring remote EJB proxy, you can instead not declare any thrown
<classname>RemoteException</classname> in your Business Method Interface and
implementing EJB code, have a remote interface which is identical except
that it does throw <classname>RemoteException</classname>, and rely on the
proxy to dynamically treat the two interfaces as if they were the same.
That is, client code does not have to deal with the checked
<classname>RemoteException</classname> class. Any actual
<classname>RemoteException</classname> that is thrown during the EJB
invocation will be re-thrown as the non-checked
<classname>RemoteAccessException</classname> class, which is a subclass of
<classname>RuntimeException</classname>. The target service can then be
switched at will between a local EJB or remote EJB (or even plain Java
object) implementation, without the client code knowing or caring. Of
course, this is optional; there is nothing stopping you from declaring
<classname>RemoteExceptions</classname> in your business interface.
</para>
</section>
<section id="ejb-access-ejb2-ejb3">
<section xml:id="ejb-access-ejb2-ejb3">
<title>Accessing EJB 2.x SLSBs versus EJB 3 SLSBs</title>
<para>
Accessing EJB 2.x Session Beans and EJB 3 Session Beans via Spring
@@ -256,12 +260,12 @@ public void setMyComponent(MyComponent myComponent) {
consistent and more explicit EJB access configuration.
</para>
</section>
</section>
</section>
<section id="ejb-implementation">
<title>Using Spring's EJB implementation support classes</title>
<section xml:id="ejb-implementation">
<title>Using Spring's EJB implementation support classes</title>
<section id="ejb-implementation-ejb2">
<section xml:id="ejb-implementation-ejb2">
<title>EJB 2.x base classes</title>
<para>
Spring provides convenience classes to help you implement EJBs.
@@ -391,7 +395,7 @@ public void setMyComponent(MyComponent myComponent) {
</para>
</section>
<section id="ejb-implementation-ejb3">
<section xml:id="ejb-implementation-ejb3">
<title>EJB 3 injection interceptor</title>
<para>
For EJB 3 Session Beans and Message-Driven Beans, Spring provides a convenient
@@ -434,6 +438,6 @@ public class MyFacadeEJB implements MyFacadeLocal {
</para>
</section>
</section>
</section>
</chapter>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="expressions"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="expressions">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Spring Expression Language (SpEL)</title>
<section id="expressions-intro">
<section xml:id="expressions-intro">
<title>Introduction</title>
<para>The Spring Expression Language (SpEL for short) is a powerful
@@ -44,7 +48,7 @@
the end of the chapter.</para>
</section>
<section id="expressions-features">
<section xml:id="expressions-features">
<title>Feature Overview</title>
<para>The expression language supports the following functionality</para>
@@ -85,16 +89,16 @@
<listitem>
<para>Calling constructors</para>
</listitem>
<listitem>
<para>Bean references</para>
</listitem>
<listitem>
<para>Array construction</para>
</listitem>
<listitem>
<listitem>
<para>Inline lists</para>
</listitem>
@@ -124,12 +128,12 @@
</itemizedlist>
</section>
<section id="expressions-evaluation">
<section xml:id="expressions-evaluation">
<title>Expression Evaluation using Spring's Expression Interface</title>
<para>This section introduces the simple use of SpEL interfaces and its
expression language. The complete language reference can be found in the
section <link lang="" linkend="expressions-language-ref">Language
section <link linkend="expressions-language-ref">Language
Reference</link>.</para>
<para>The following code introduces the SpEL API to evaluate the literal
@@ -173,7 +177,7 @@ String message = (String) exp.getValue();</programlisting>
<programlisting language="java">ExpressionParser parser = new SpelExpressionParser();
// invokes 'getBytes()'
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.bytes</emphasis>");
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.bytes</emphasis>");
byte[] bytes = (byte[]) exp.getValue();</programlisting>
@@ -185,7 +189,7 @@ byte[] bytes = (byte[]) exp.getValue();</programlisting>
<programlisting language="java">ExpressionParser parser = new SpelExpressionParser();
// invokes 'getBytes().length'
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.bytes.length</emphasis>");
Expression exp = parser.parseExpression("<emphasis role="bold">'Hello World'.bytes.length</emphasis>");
int length = (Integer) exp.getValue();</programlisting>
@@ -204,14 +208,14 @@ String message = exp.getValue(String.class);</programlisting>
the registered type converter.</para>
<para>The more common usage of SpEL is to provide an expression string that
is evaluated against a specific object instance (called the root object).
There are two options here and which to choose depends on whether the object
against which the expression is being evaluated will be changing with each
is evaluated against a specific object instance (called the root object).
There are two options here and which to choose depends on whether the object
against which the expression is being evaluated will be changing with each
call to evaluate the expression. In the following example
we retrieve the <literal>name</literal> property from an instance of the
Inventor class.</para>
<programlisting language="java">// Create and set a calendar
<programlisting language="java">// Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
@@ -229,10 +233,10 @@ String name = (String) exp.getValue(context);</programlisting>
object the "name" property will be evaluated against. This is the mechanism
to use if the root object is unlikely to change, it can simply be set once
in the evaluation context. If the root object is likely to change
repeatedly, it can be supplied on each call to <literal>getValue</literal>,
repeatedly, it can be supplied on each call to <literal>getValue</literal>,
as this next example shows:</para>
<programlisting language="java">/ Create and set a calendar
<programlisting language="java">/ Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
@@ -245,13 +249,13 @@ Expression exp = parser.parseExpression("<emphasis role="bold">name</emphasis>")
String name = (String) exp.getValue(tesla);
</programlisting><para>In this case the inventor <literal>tesla</literal> has been
supplied directly to <literal>getValue</literal> and the expression
evaluation infrastructure creates and manages a default evaluation context
evaluation infrastructure creates and manages a default evaluation context
internally - it did not require one to be supplied.</para>
<para>The StandardEvaluationContext is relatively expensive to construct and
during repeated usage it builds up cached state that enables subsequent
expression evaluations to be performed more quickly. For this reason it is
better to cache and reuse them where possible, rather than construct a new
better to cache and reuse them where possible, rather than construct a new
one for each expression evaluation.
</para>
<para>In some cases it can be desirable to use a configured evaluation context and
@@ -261,7 +265,7 @@ String name = (String) exp.getValue(tesla);
any (which maybe null) specified on the evaluation context.</para>
<para>
<note>
<note>
<para>In standalone usage of SpEL there is a need to create the parser,
parse expressions and perhaps provide evaluation contexts and a root
context object. However, more common usage
@@ -271,13 +275,13 @@ String name = (String) exp.getValue(tesla);
and any predefined variables are all set up implicitly, requiring
the user to specify nothing other than the expressions.</para>
</note>
As a final introductory example, the use of a boolean operator is
As a final introductory example, the use of a boolean operator is
shown using the Inventor object in the previous example.</para>
<programlisting language="java">Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(context, Boolean.class); // evaluates to true</programlisting>
<section id="expressions-evaluation-context">
<section xml:id="expressions-evaluation-context">
<title>The EvaluationContext interface</title>
<para>The interface <interfacename>EvaluationContext</interfacename> is
@@ -297,7 +301,7 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to true</pr
<methodname>setVariable()</methodname> and
<methodname>registerFunction()</methodname>. The use of variables and
functions are described in the language reference sections <link
linkend="expressions-ref-variables">Variables</link> and <link lang=""
linkend="expressions-ref-variables">Variables</link> and <link
linkend="expressions-ref-functions">Functions</link>. The
<classname>StandardEvaluationContext</classname> is also where you can
register custom <classname>ConstructorResolver</classname>s,
@@ -306,7 +310,7 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to true</pr
expressions. Please refer to the JavaDoc of these classes for more
details.</para>
<section id="expressions-type-conversion">
<section xml:id="expressions-type-conversion">
<title>Type Conversion</title>
<para>By default SpEL uses the conversion service available in Spring
@@ -330,14 +334,14 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to true</pr
<programlisting language="java">class Simple {
public List&lt;Boolean&gt; booleanList = new ArrayList&lt;Boolean&gt;();
}
Simple simple = new Simple();
simple.booleanList.add(true);
StandardEvaluationContext simpleContext = new StandardEvaluationContext(simple);
// false is passed in here as a string. SpEL and the conversion service will
// false is passed in here as a string. SpEL and the conversion service will
// correctly recognize that it needs to be a Boolean and convert it
parser.parseExpression("booleanList[0]").setValue(simpleContext, "false");
@@ -348,7 +352,7 @@ Boolean b = simple.booleanList.get(0);
</section>
</section>
<section id="expressions-beandef">
<section xml:id="expressions-beandef">
<title>Expression support for defining bean definitions</title>
<para>SpEL expressions can be used with XML or annotation based
@@ -356,7 +360,7 @@ Boolean b = simple.booleanList.get(0);
syntax to define the expression is of the form <literal>#{ &lt;expression
string&gt; }</literal>.</para>
<section id="expressions-beandef-xml-based">
<section xml:id="expressions-beandef-xml-based">
<title>XML based configuration</title>
<para>A property or constructor-arg value can be set using expressions
@@ -395,7 +399,7 @@ Boolean b = simple.booleanList.get(0);
&lt;/bean&gt;</programlisting></para>
</section>
<section id="expressions-beandef-annotation-based">
<section xml:id="expressions-beandef-annotation-based">
<title>Annotation-based configuration</title>
<para>The <literal>@Value</literal> annotation can be placed on fields,
@@ -415,7 +419,7 @@ Boolean b = simple.booleanList.get(0);
this.defaultLocale = defaultLocale;
}
public String getDefaultLocale()
public String getDefaultLocale()
{
return this.defaultLocale;
}
@@ -437,7 +441,7 @@ Boolean b = simple.booleanList.get(0);
this.defaultLocale = defaultLocale;
}
public String getDefaultLocale()
public String getDefaultLocale()
{
return this.defaultLocale;
}
@@ -453,7 +457,7 @@ Boolean b = simple.booleanList.get(0);
private String defaultLocale;
@Autowired
public void configure(MovieFinder movieFinder,
public void configure(MovieFinder movieFinder,
@Value("#{ systemProperties['user.region'] }"} String defaultLocale) {
this.movieFinder = movieFinder;
this.defaultLocale = defaultLocale;
@@ -480,10 +484,10 @@ Boolean b = simple.booleanList.get(0);
</section>
</section>
<section id="expressions-language-ref">
<section xml:id="expressions-language-ref">
<title>Language Reference</title>
<section id="expressions-ref-literal">
<section xml:id="expressions-ref-literal">
<title>Literal expressions</title>
<para>The types of literal expressions supported are strings, dates,
@@ -497,12 +501,12 @@ Boolean b = simple.booleanList.get(0);
<programlisting language="java">ExpressionParser parser = new SpelExpressionParser();
// evals to "Hello World"
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();
double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();
// evals to 2147483647
int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();
int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();
boolean trueValue = (Boolean) parser.parseExpression("true").getValue();
@@ -514,7 +518,7 @@ Object nullValue = parser.parseExpression("null").getValue();
Double.parseDouble().</para>
</section>
<section id="expressions-properties-arrays">
<section xml:id="expressions-properties-arrays">
<title>Properties, Arrays, Lists, Maps, Indexers</title>
<para>Navigating with property references is easy, just use a period to
@@ -524,8 +528,8 @@ Object nullValue = parser.parseExpression("null").getValue();
examples</link>. To navigate "down" and get Tesla's year of birth and
Pupin's city of birth the following expressions are used.</para>
<programlisting lang="" language="java">// evals to 1856
int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context);
<programlisting language="java">// evals to 1856
int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context);
String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context);</programlisting>
@@ -540,8 +544,8 @@ String city = (String) parser.parseExpression("placeOfBirth.City").getValue(cont
StandardEvaluationContext teslaContext = new StandardEvaluationContext(tesla);
// evaluates to "Induction motor"
String invention = parser.parseExpression("inventions[3]").getValue(teslaContext,
String.class);
String invention = parser.parseExpression("inventions[3]").getValue(teslaContext,
String.class);
// Members List
@@ -562,11 +566,11 @@ String invention = parser.parseExpression("Members[0].Inventions[6]").getValue(s
<programlisting language="java">// Officer's Dictionary
Inventor pupin = parser.parseExpression("Officers['president']").getValue(societyContext,
Inventor pupin = parser.parseExpression("Officers['president']").getValue(societyContext,
Inventor.class);
// evaluates to "Idvor"
String city =
String city =
parser.parseExpression("Officers['president'].PlaceOfBirth.City").getValue(societyContext,
String.class);
@@ -576,43 +580,43 @@ parser.parseExpression("Officers['advisors'][0].PlaceOfBirth.Country").setValue(
</programlisting>
</section>
<section id="expressions-inline-lists">
<section xml:id="expressions-inline-lists">
<title>Inline lists</title>
<para>Lists can be expressed directly in an expression using {} notation.
</para>
<programlisting lang="" language="java">
<programlisting language="java">
// evaluates to a Java list containing the four numbers
List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context);
List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context);
List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context);
List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context);
</programlisting>
<para>{} by itself means an empty list. For performance reasons, if the
list is itself entirely composed of fixed literals then a constant list is created
to represent the expression, rather than building a new list on each evaluation.</para>
</section>
<section id="expressions-array-construction">
</section>
<section xml:id="expressions-array-construction">
<title>Array construction</title>
<para>Arrays can be built using the familiar Java syntax, optionally
supplying an initializer to have the array populated at construction time.
</para>
<programlisting lang="" language="java">int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context);
<programlisting language="java">int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context);
// Array with initializer
int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context);
int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context);
// Multi dimensional array
int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context);
int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context);
</programlisting>
<para>It is not currently allowed to supply an initializer when constructing
a multi-dimensional array.</para>
</section>
<section id="expressions-methods">
</section>
<section xml:id="expressions-methods">
<title>Methods</title>
<para>Methods are invoked using typical Java programming syntax. You may
@@ -626,10 +630,10 @@ boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
Boolean.class);</programlisting>
</section>
<section id="expressions-operators">
<section xml:id="expressions-operators">
<title>Operators</title>
<section id="expressions-operators-relational">
<section xml:id="expressions-operators-relational">
<title>Relational operators</title>
<para>The relational operators; equal, not equal, less than, less than
@@ -651,23 +655,23 @@ boolean trueValue = parser.parseExpression("'black' &lt; 'block'").getValue(Bool
boolean falseValue = parser.parseExpression("'xyz' instanceof T(int)").getValue(Boolean.class);
// evaluates to true
boolean trueValue =
boolean trueValue =
parser.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
//evaluates to false
boolean falseValue =
boolean falseValue =
parser.parseExpression("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
</programlisting>
<para>Each symbolic operator can also be specified as a purely alphabetic equivalent. This avoids
problems where the symbols used have special meaning for the document type in which
problems where the symbols used have special meaning for the document type in which
the expression is embedded (eg. an XML document). The textual equivalents are shown
here: lt ('&lt;'), gt ('&gt;'), le ('&lt;='), ge ('&gt;='),
eq ('=='), ne ('!='), div ('/'), mod ('%'), not ('!').
These are case insensitive.</para>
</section>
<section id="expressions-operators-logical">
<section xml:id="expressions-operators-logical">
<title>Logical operators</title>
<para>The logical operators that are supported are and, or, and not.
@@ -702,7 +706,7 @@ String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);</programlisting></para>
</section>
<section id="expressions-operators-mathematical">
<section xml:id="expressions-operators-mathematical">
<title>Mathematical operators</title>
<para>The addition operator can be used on numbers, strings and dates.
@@ -714,7 +718,7 @@ boolean falseValue = parser.parseExpression(expression).getValue(societyContext,
<para><programlisting language="java">// Addition
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
String testString =
String testString =
parser.parseExpression("'test' + ' ' + 'string'").getValue(String.class); // 'test string'
// Subtraction
@@ -743,7 +747,7 @@ int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class);
</section>
</section>
<section id="expressions-assignment">
<section xml:id="expressions-assignment">
<title>Assignment</title>
<para>Setting of a property is done by using the assignment operator.
@@ -751,21 +755,21 @@ int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class);
<literal>setValue</literal> but can also be done inside a call to
<literal>getValue</literal>.</para>
<programlisting language="java">Inventor inventor = new Inventor();
<programlisting language="java">Inventor inventor = new Inventor();
StandardEvaluationContext inventorContext = new StandardEvaluationContext(inventor);
parser.parseExpression("Name").setValue(inventorContext, "Alexander Seovic2");
// alternatively
String aleks = parser.parseExpression("Name = 'Alexandar Seovic'").getValue(inventorContext,
String aleks = parser.parseExpression("Name = 'Alexandar Seovic'").getValue(inventorContext,
String.class);
</programlisting>
<para></para>
</section>
<section id="expressions-types">
<section xml:id="expressions-types">
<title>Types</title>
<para>The special 'T' operator can be used to specify an instance of
@@ -781,21 +785,21 @@ String aleks = parser.parseExpression("Name = 'Alexandar Seovic'").getValue(inve
Class stringClass = parser.parseExpression("T(String)").getValue(Class.class);
boolean trueValue =
boolean trueValue =
parser.parseExpression("T(java.math.RoundingMode).CEILING &lt; T(java.math.RoundingMode).FLOOR")
.getValue(Boolean.class);
</programlisting>
</section>
<section id="expressions-constructors">
<section xml:id="expressions-constructors">
<title>Constructors</title>
<para>Constructors can be invoked using the new operator. The fully
qualified class name should be used for all but the primitive type and
String (where int, float, etc, can be used).</para>
<programlisting language="java">Inventor einstein =
p.parseExpression("new org.spring.samples.spel.inventor.Inventor('Albert Einstein',
<programlisting language="java">Inventor einstein =
p.parseExpression("new org.spring.samples.spel.inventor.Inventor('Albert Einstein',
'German')")
.getValue(Inventor.class);
@@ -806,7 +810,7 @@ p.parseExpression("Members.add(new org.spring.samples.spel.inventor.Inventor('Al
</programlisting>
</section>
<section id="expressions-ref-variables">
<section xml:id="expressions-ref-variables">
<title>Variables</title>
<para>Variables can be referenced in the expression using the syntax
@@ -821,7 +825,7 @@ parser.parseExpression("Name = #newName").getValue(context);
System.out.println(tesla.getName()) // "Mike Tesla"</programlisting>
<section id="expressions-this-root">
<section xml:id="expressions-this-root">
<title>The #this and #root variables</title>
<para>The variable #this is always defined and refers to the current
@@ -841,21 +845,21 @@ context.setVariable("primes",primes);
// all prime numbers &gt; 10 from the list (using selection ?{...})
// evaluates to [11, 13, 17]
List&lt;Integer&gt; primesGreaterThanTen =
List&lt;Integer&gt; primesGreaterThanTen =
(List&lt;Integer&gt;) parser.parseExpression("#primes.?[#this&gt;10]").getValue(context);
</programlisting>
</section>
<!--
<section id="expressions-root">
<section xml:id="expressions-root">
<title>The #root variable</title>
<para>The variable #root is always defined and refers to the
root evaluation object. This is the object against which the first unqualified
root evaluation object. This is the object against which the first unqualified
reference to a property or method is resolved.</para>
<para>It differs from #this in that #this typically varies throughout the
<para>It differs from #this in that #this typically varies throughout the
evaluation of an expression, whilst #root remains constant.
It can be useful when writing a selection criteria, where the decision
needs to be made based on some property of the root object rather than the
@@ -867,7 +871,7 @@ List&lt;Integer&gt; primesGreaterThanTen =
-->
</section>
<section id="expressions-ref-functions">
<section xml:id="expressions-ref-functions">
<title>Functions</title>
<para>You can extend SpEL by registering user defined functions that can
@@ -885,7 +889,7 @@ List&lt;Integer&gt; primesGreaterThanTen =
public static String reverseString(String input) {
StringBuilder backwards = new StringBuilder();
for (int i = 0; i &lt; input.length(); i++)
for (int i = 0; i &lt; input.length(); i++)
backwards.append(input.charAt(input.length() - 1 - i));
}
return backwards.toString();
@@ -898,19 +902,19 @@ List&lt;Integer&gt; primesGreaterThanTen =
<programlisting language="java">ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.registerFunction("reverseString",
StringUtils.class.getDeclaredMethod("reverseString",
context.registerFunction("reverseString",
StringUtils.class.getDeclaredMethod("reverseString",
new Class[] { String.class }));
String helloWorldReversed =
String helloWorldReversed =
parser.parseExpression("#reverseString('hello')").getValue(context, String.class);</programlisting>
</section>
<section id="expressions-bean-references">
<title>Bean references</title>
<para>If the evaluation context has been configured with a bean resolver it is possible to
lookup beans from an expression using the (@) symbol.
</para>
<section xml:id="expressions-bean-references">
<title>Bean references</title>
<para>If the evaluation context has been configured with a bean resolver it is possible to
lookup beans from an expression using the (@) symbol.
</para>
<programlisting language="java">ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());
@@ -918,14 +922,14 @@ context.setBeanResolver(new MyBeanResolver());
// This will end up calling resolve(context,"foo") on MyBeanResolver during evaluation
Object bean = parser.parseExpression("@foo").getValue(context);</programlisting>
</section>
<section id="expressions-operator-ternary">
<section xml:id="expressions-operator-ternary">
<title>Ternary Operator (If-Then-Else)</title>
<para>You can use the ternary operator for performing if-then-else
conditional logic inside the expression. A minimal example is:</para>
<programlisting language="java">String falseString =
<programlisting language="java">String falseString =
parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(String.class);</programlisting>
<para>In this case, the boolean false results in returning the string
@@ -934,10 +938,10 @@ Object bean = parser.parseExpression("@foo").getValue(context);</programlisting>
<programlisting language="java">parser.parseExpression("Name").setValue(societyContext, "IEEE");
societyContext.setVariable("queryName", "Nikola Tesla");
expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +
expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +
"+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";
String queryResultString =
String queryResultString =
parser.parseExpression(expression).getValue(societyContext, String.class);
// queryResultString = "Nikola Tesla is a member of the IEEE Society"</programlisting>
@@ -945,12 +949,11 @@ String queryResultString =
shorter syntax for the ternary operator.</para>
</section>
<section id="expressions-operator-elvis">
<section xml:id="expressions-operator-elvis">
<title>The Elvis Operator</title>
<para>The Elvis operator is a shortening of the ternary operator syntax
and is used in the <ulink
url="http://groovy.codehaus.org/Operators#Operators-ElvisOperator(%3F%3A)">Groovy</ulink>
and is used in the <link xl:href="http://groovy.codehaus.org/Operators#Operators-ElvisOperator(%3F%3A)">Groovy</link>
language. With the ternary operator syntax you usually have to repeat a
variable twice, for example:</para>
@@ -986,12 +989,12 @@ name = parser.parseExpression("Name?:'Elvis Presley'").getValue(context, String.
System.out.println(name); // Elvis Presley</programlisting>
</section>
<section id="expressions-operator-safe-navigation">
<section xml:id="expressions-operator-safe-navigation">
<title>Safe Navigation operator</title>
<para>The Safe Navigation operator is used to avoid a
<literal>NullPointerException</literal> and comes from the <ulink
url="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator(%3F.)">Groovy</ulink>
<literal>NullPointerException</literal> and comes from the <link
xl:href="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator(%3F.)">Groovy</link>
language. Typically when you have a reference to an object you might
need to verify that it is not null before accessing methods or
properties of the object. To avoid this, the safe navigation operator
@@ -1023,7 +1026,7 @@ System.out.println(city); // null - does not throw NullPointerException!!!</prog
</note>
</section>
<section id="expressions-collection-selection">
<section xml:id="expressions-collection-selection">
<title>Collection Selection</title>
<para>Selection is a powerful expression language feature that allows you
@@ -1036,7 +1039,7 @@ System.out.println(city); // null - does not throw NullPointerException!!!</prog
original elements. For example, selection would allow us to easily get a
list of Serbian inventors:</para>
<programlisting language="java">List&lt;Inventor&gt; list = (List&lt;Inventor&gt;)
<programlisting language="java">List&lt;Inventor&gt; list = (List&lt;Inventor&gt;)
parser.parseExpression("Members.?[Nationality == 'Serbian']").getValue(societyContext);</programlisting>
<para>Selection is possible upon both lists and maps. In the former case
@@ -1058,7 +1061,7 @@ System.out.println(city); // null - does not throw NullPointerException!!!</prog
<literal>$[...]</literal>.</para>
</section>
<section id="expressions-collection-projection">
<section xml:id="expressions-collection-projection">
<title>Collection Projection</title>
<para>Projection allows a collection to drive the evaluation of a
@@ -1079,7 +1082,7 @@ List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]"
projection expression against each map entry.</para>
</section>
<section id="expressions-templating">
<section xml:id="expressions-templating">
<title>Expression templating</title>
<para>Expression templates allow a mixing of literal text with one or
@@ -1087,8 +1090,8 @@ List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]"
and suffix characters that you can define, a common choice is to use
<literal>#{ }</literal> as the delimiters. For example,</para>
<programlisting language="java">String randomPhrase =
parser.parseExpression("random number is #{T(java.lang.Math).random()}",
<programlisting language="java">String randomPhrase =
parser.parseExpression("random number is #{T(java.lang.Math).random()}",
new TemplateParserContext()).getValue(String.class);
// evaluates to "random number is 0.7038186818312008"</programlisting>
@@ -1112,7 +1115,7 @@ List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]"
public String getExpressionSuffix() {
return "}";
}
public boolean isTemplate() {
return true;
}
@@ -1120,7 +1123,7 @@ List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]"
</section>
</section>
<section id="expressions-example-classes">
<section xml:id="expressions-example-classes">
<title>Classes used in the examples</title>
<para>Inventor.java</para>
@@ -1137,8 +1140,8 @@ public class Inventor {
private String[] inventions;
private Date birthdate;
private PlaceOfBirth placeOfBirth;
public Inventor(String name, String nationality)
{
GregorianCalendar c= new GregorianCalendar();
@@ -1151,7 +1154,7 @@ public class Inventor {
this.nationality = nationality;
this.birthdate = birthdate;
}
public Inventor() {
}
@@ -1184,7 +1187,7 @@ public class Inventor {
}
public String[] getInventions() {
return inventions;
}
}
}
</programlisting>
@@ -1194,34 +1197,34 @@ public class Inventor {
public class PlaceOfBirth {
private String city;
private String country;
public PlaceOfBirth(String city) {
this.city=city;
}
public PlaceOfBirth(String city, String country)
{
this(city);
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String s) {
this.city = s;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
private String city;
private String country;
public PlaceOfBirth(String city) {
this.city=city;
}
public PlaceOfBirth(String city, String country)
{
this(city);
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String s) {
this.city = s;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
</programlisting>
@@ -1233,44 +1236,44 @@ import java.util.*;
public class Society {
private String name;
public static String Advisors = "advisors";
public static String President = "president";
private List&lt;Inventor&gt; members = new ArrayList&lt;Inventor&gt;();
private Map officers = new HashMap();
private String name;
public List getMembers() {
return members;
}
public static String Advisors = "advisors";
public static String President = "president";
public Map getOfficers() {
return officers;
}
private List&lt;Inventor&gt; members = new ArrayList&lt;Inventor&gt;();
private Map officers = new HashMap();
public String getName() {
return name;
}
public List getMembers() {
return members;
}
public void setName(String name) {
this.name = name;
}
public Map getOfficers() {
return officers;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isMember(String name)
{
boolean found = false;
for (Inventor inventor : members) {
if (inventor.getName().equals(name))
{
found = true;
break;
}
}
return found;
}
public boolean isMember(String name)
{
boolean found = false;
for (Inventor inventor : members) {
if (inventor.getName().equals(name))
{
found = true;
break;
}
}
return found;
}
}
</programlisting>
</section>

View File

@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://docbook.org/ns/docbook" version="5.0"
xml:id="spring-framework-reference"
<book xml:id="spring-framework-reference"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink">
<bookinfo>
<title>Spring Framework Reference Manual</title>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<info>
<title>Spring Framework Reference Documentation</title>
<productname>Spring Framework</productname>
@@ -19,171 +24,199 @@
<authorgroup>
<author>
<firstname>Rod</firstname>
<surname>Johnson</surname>
<personname>
<firstname>Rod</firstname>
<surname>Johnson</surname>
</personname>
</author>
<author>
<firstname>Juergen</firstname>
<surname>Hoeller</surname>
<personname>
<firstname>Juergen</firstname>
<surname>Hoeller</surname>
</personname>
</author>
<author>
<firstname>Keith</firstname>
<surname>Donald</surname>
<personname>
<firstname>Keith</firstname>
<surname>Donald</surname>
</personname>
</author>
<author>
<firstname>Colin</firstname>
<surname>Sampaleanu</surname>
<personname>
<firstname>Colin</firstname>
<surname>Sampaleanu</surname>
</personname>
</author>
<author>
<firstname>Rob</firstname>
<surname>Harrop</surname>
<personname>
<firstname>Rob</firstname>
<surname>Harrop</surname>
</personname>
</author>
<author>
<firstname>Thomas</firstname>
<surname>Risberg</surname>
<personname>
<firstname>Thomas</firstname>
<surname>Risberg</surname>
</personname>
</author>
<author>
<firstname>Alef</firstname>
<surname>Arendsen</surname>
<personname>
<firstname>Alef</firstname>
<surname>Arendsen</surname>
</personname>
</author>
<author>
<firstname>Darren</firstname>
<surname>Davison</surname>
<personname>
<firstname>Darren</firstname>
<surname>Davison</surname>
</personname>
</author>
<author>
<firstname>Dmitriy</firstname>
<surname>Kopylenko</surname>
<personname>
<firstname>Dmitriy</firstname>
<surname>Kopylenko</surname>
</personname>
</author>
<author>
<firstname>Mark</firstname>
<surname>Pollack</surname>
<personname>
<firstname>Mark</firstname>
<surname>Pollack</surname>
</personname>
</author>
<author>
<firstname>Thierry</firstname>
<surname>Templier</surname>
<personname>
<firstname>Thierry</firstname>
<surname>Templier</surname>
</personname>
</author>
<author>
<firstname>Erwin</firstname>
<surname>Vervaet</surname>
<personname>
<firstname>Erwin</firstname>
<surname>Vervaet</surname>
</personname>
</author>
<author>
<firstname>Portia</firstname>
<surname>Tung</surname>
<personname>
<firstname>Portia</firstname>
<surname>Tung</surname>
</personname>
</author>
<author>
<firstname>Ben</firstname>
<surname>Hale</surname>
<personname>
<firstname>Ben</firstname>
<surname>Hale</surname>
</personname>
</author>
<author>
<firstname>Adrian</firstname>
<surname>Colyer</surname>
<personname>
<firstname>Adrian</firstname>
<surname>Colyer</surname>
</personname>
</author>
<author>
<firstname>John</firstname>
<surname>Lewis</surname>
<personname>
<firstname>John</firstname>
<surname>Lewis</surname>
</personname>
</author>
<author>
<firstname>Costin</firstname>
<surname>Leau</surname>
<personname>
<firstname>Costin</firstname>
<surname>Leau</surname>
</personname>
</author>
<author>
<firstname>Mark</firstname>
<surname>Fisher</surname>
<personname>
<firstname>Mark</firstname>
<surname>Fisher</surname>
</personname>
</author>
<author>
<firstname>Sam</firstname>
<surname>Brannen</surname>
<personname>
<firstname>Sam</firstname>
<surname>Brannen</surname>
</personname>
</author>
<author>
<firstname>Ramnivas</firstname>
<surname>Laddad</surname>
<personname>
<firstname>Ramnivas</firstname>
<surname>Laddad</surname>
</personname>
</author>
<author>
<firstname>Arjen</firstname>
<surname>Poutsma</surname>
<personname>
<firstname>Arjen</firstname>
<surname>Poutsma</surname>
</personname>
</author>
<author>
<firstname>Chris</firstname>
<surname>Beams</surname>
<personname>
<firstname>Chris</firstname>
<surname>Beams</surname>
</personname>
</author>
<author>
<firstname>Tareq</firstname>
<surname>Abedrabbo</surname>
<personname>
<firstname>Tareq</firstname>
<surname>Abedrabbo</surname>
</personname>
</author>
<author>
<firstname>Andy</firstname>
<surname>Clement</surname>
<personname>
<firstname>Andy</firstname>
<surname>Clement</surname>
</personname>
</author>
<author>
<firstname>Dave</firstname>
<surname>Syer</surname>
</author>
<author>
<firstname>Oliver</firstname>
<surname>Gierke</surname>
<personname>
<firstname>Dave</firstname>
<surname>Syer</surname>
</personname>
</author>
<author>
<firstname>Rossen</firstname>
<surname>Stoyanchev</surname>
<personname>
<firstname>Oliver</firstname>
<surname>Gierke</surname>
</personname>
</author>
<author>
<firstname>Phillip</firstname>
<personname>
<firstname>Rossen</firstname>
<surname>Stoyanchev</surname>
</personname>
</author>
<surname>Webb</surname>
<author>
<personname>
<firstname>Phillip</firstname>
<surname>Webb</surname>
</personname>
</author>
</authorgroup>
@@ -206,16 +239,16 @@
copies and further provided that each copy contains this Copyright
Notice, whether distributed in print or electronically.</para>
</legalnotice>
</bookinfo>
</info>
<!-- front matter -->
<toc></toc>
<part id="spring-introduction">
<part xml:id="spring-introduction">
<title>Overview of Spring Framework</title>
<partintro id="spring-core-intro">
<partintro>
<para>The Spring Framework is a lightweight solution and a potential
one-stop-shop for building your enterprise-ready applications. However,
Spring is modular, allowing you to use only those parts that you need,
@@ -240,13 +273,13 @@
<para>This document is a reference guide to Spring Framework features.
If you have any requests, comments, or questions on this document,
please post them on the user mailing list or on the support forums at
<ulink url="http://forum.springsource.org/"></ulink>.<!-- Missing link above. PDF shows it as http://forum.springsource.org/ --></para>
<link xl:href="http://forum.springsource.org/"></link>.<!-- Missing link above. PDF shows it as http://forum.springsource.org/ --></para>
</partintro>
<xi:include href="overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part id="spring-whats-new">
<part xml:id="spring-whats-new">
<title>What's New in Spring 3</title>
<xi:include href="new-in-3.0.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
@@ -254,10 +287,10 @@
<xi:include href="new-in-3.2.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part id="spring-core">
<part xml:id="spring-core">
<title>Core Technologies</title>
<partintro id="spring-core-intro">
<partintro>
<para>This part of the reference documentation covers all of those
technologies that are absolutely integral to the Spring
Framework.</para>
@@ -334,10 +367,10 @@
<xi:include href="testing.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part id="spring-data-tier">
<part xml:id="spring-data-tier">
<title>Data Access</title>
<partintro id="spring-data-tier-intro">
<partintro xml:id="spring-data-tier-intro">
<para>This part of the reference documentation is concerned with data
access and the interaction between the data access layer and the
business or service layer.</para>
@@ -382,10 +415,10 @@
<xi:include href="oxm.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part id="spring-web">
<part xml:id="spring-web">
<title>The Web</title>
<partintro id="spring-web-intro">
<partintro>
<para>This part of the reference documentation covers the Spring
Framework's support for the presentation tier (and specifically
web-based presentation tiers).</para>
@@ -430,10 +463,10 @@
<xi:include href="portlet.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part id="spring-integration">
<part xml:id="spring-integration">
<title>Integration</title>
<partintro id="spring-integration-intro">
<partintro>
<para>This part of the reference documentation covers the Spring
Framework's integration with a number of Java EE (and related)
technologies.</para>
@@ -494,12 +527,12 @@
<xi:include href="dynamic-languages.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="cache.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part id="spring-appendices">
<part xml:id="spring-appendices">
<title>Appendices</title>
<xi:include href="classic-spring.xml"

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="jdbc"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="jdbc">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Data access with JDBC</title>
<section id="jdbc-introduction">
<section xml:id="jdbc-introduction">
<title>Introduction to Spring Framework JDBC</title>
<para>The value-add provided by the Spring Framework JDBC abstraction is
@@ -122,7 +126,7 @@
<para>The Spring Framework takes care of all the low-level details that
can make JDBC such a tedious API to develop with.</para>
<section id="jdbc-choose-style">
<section xml:id="jdbc-choose-style">
<title>Choosing an approach for JDBC database access</title>
<para>You can choose among several approaches to form the basis for your
@@ -166,7 +170,7 @@
SimpleJdbcCall</emphasis> optimize database metadata to limit the
amount of necessary configuration. This approach simplifies coding
so that you only need to provide the name of the table or procedure
and provide a map of parameters matching the column names. <!--Revise preceding to clarify: You *must* use this approach w/ SimpleJdbcTemplate, it is *recommended*, or you *can*?
and provide a map of parameters matching the column names. <!--Revise preceding to clarify: You *must* use this approach w/ SimpleJdbcTemplate, it is *recommended*, or you *can*?
TR: OK. I removed the sentence since it isn;t entirely accurate. The implementation uses a plain JdbcTemplate internally.-->
This only works if the database provides adequate metadata. If the
database doesn't provide this metadata, you will have to provide
@@ -185,7 +189,7 @@ TR: OK. I removed the sentence since it isn;t entirely accurate. The implementat
</itemizedlist>
</section>
<section id="jdbc-packages">
<section xml:id="jdbc-packages">
<title>Package hierarchy<!--I have provided links to main sections that deal with most packages. TR: OK--></title>
<para>The Spring Framework's JDBC abstraction framework consists of four
@@ -240,11 +244,11 @@ TR: OK. I removed the sentence since it isn;t entirely accurate. The implementat
</section>
</section>
<section id="jdbc-core">
<section xml:id="jdbc-core">
<title>Using the JDBC core classes to control basic JDBC processing and
error handling<!--Note: I moved the *DataSource* subsection out of this section because it seems to belong more under *Controlling database connections.*--><!--This section here is about core classes, but datasource is a separate package from core. See *Package hierarchy* section above. TR: OK--></title>
<section id="jdbc-JdbcTemplate">
<section xml:id="jdbc-JdbcTemplate">
<title><classname>JdbcTemplate</classname></title>
<para>The <classname>JdbcTemplate</classname> class is the central class
@@ -293,7 +297,7 @@ TR: OK. I removed the sentence since it isn;t entirely accurate. The implementat
using a custom subclass of the <classname>JdbcTemplate</classname>
class).</para>
<section id="jdbc-JdbcTemplate-examples">
<section xml:id="jdbc-JdbcTemplate-examples">
<title>Examples of JdbcTemplate class usage</title>
<para>This section provides some examples of
@@ -302,7 +306,7 @@ TR: OK. I removed the sentence since it isn;t entirely accurate. The implementat
<classname>JdbcTemplate</classname>; see the attendant Javadocs for
that.</para>
<section id="jdbc-JdbcTemplate-examples-query">
<section xml:id="jdbc-JdbcTemplate-examples-query">
<title>Querying (SELECT)</title>
<para>Here is a simple query for getting the number of rows in a
@@ -318,7 +322,7 @@ TR: OK. I removed the sentence since it isn;t entirely accurate. The implementat
<para>Querying for a <classname>String</classname>:</para>
<programlisting language="java">String lastName = this.jdbcTemplate.queryForObject(
"select last_name from t_actor where id = ?",
"select last_name from t_actor where id = ?",
new Object[]{1212L}, String.class);</programlisting>
<para>Querying and populating a <emphasis>single</emphasis> domain
@@ -370,11 +374,11 @@ private static final class ActorMapper implements RowMapper&lt;Actor&gt; {
actor.setFirstName(rs.getString("first_name"));
actor.setLastName(rs.getString("last_name"));
return actor;
}
}
}</programlisting>
</section>
<section id="jdbc-JdbcTemplate-examples-update">
<section xml:id="jdbc-JdbcTemplate-examples-update">
<title>Updating (INSERT/UPDATE/DELETE) with jdbcTemplate<!--Provide introductory text as with other examples. TR: OK.--></title>
<para>You use the <methodname>update(..)</methodname> method to
@@ -383,11 +387,11 @@ private static final class ActorMapper implements RowMapper&lt;Actor&gt; {
array.</para>
<programlisting language="java">this.jdbcTemplate.update(
"insert into t_actor (first_name, last_name) values (?, ?)",
"insert into t_actor (first_name, last_name) values (?, ?)",
"Leonor", "Watling");</programlisting>
<programlisting language="java">this.jdbcTemplate.update(
"update t_actor set = ? where id = ?",
"update t_actor set = ? where id = ?",
"Banjo", 5276L);</programlisting>
<programlisting language="java">this.jdbcTemplate.update(
@@ -395,7 +399,7 @@ private static final class ActorMapper implements RowMapper&lt;Actor&gt; {
Long.valueOf(actorId));</programlisting>
</section>
<section id="jdbc-JdbcTemplate-examples-other">
<section xml:id="jdbc-JdbcTemplate-examples-other">
<title>Other jdbcTemplate operations</title>
<para>You can use the <methodname>execute(..)</methodname> method to
@@ -410,12 +414,12 @@ private static final class ActorMapper implements RowMapper&lt;Actor&gt; {
linkend="jdbc-StoredProcedure">covered later</link>.</para>
<programlisting language="java">this.jdbcTemplate.update(
"call SUPPORT.REFRESH_ACTORS_SUMMARY(?)",
"call SUPPORT.REFRESH_ACTORS_SUMMARY(?)",
Long.valueOf(unionId));</programlisting>
</section>
</section>
<section id="jdbc-JdbcTemplate-idioms">
<section xml:id="jdbc-JdbcTemplate-idioms">
<title><classname>JdbcTemplate</classname> best practices</title>
<para>Instances of the <classname>JdbcTemplate</classname> class are
@@ -448,7 +452,7 @@ private static final class ActorMapper implements RowMapper&lt;Actor&gt; {
<emphasis role="bold">this.jdbcTemplate = new JdbcTemplate(dataSource);</emphasis>
}
<lineannotation>// JDBC-backed implementations of the methods on the <interfacename>CorporateEventDao</interfacename> follow...</lineannotation>
<lineannotation>// JDBC-backed implementations of the methods on the CorporateEventDao follow...</lineannotation>
}</programlisting>
<para>The corresponding configuration might look like this.</para>
@@ -462,11 +466,11 @@ private static final class ActorMapper implements RowMapper&lt;Actor&gt; {
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
&lt;bean id="corporateEventDao" class="com.example.JdbcCorporateEventDao"&gt;
&lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
&lt;property name="driverClassName" value="${jdbc.driverClassName}"/&gt;
&lt;property name="url" value="${jdbc.url}"/&gt;
@@ -496,7 +500,7 @@ public class JdbcCorporateEventDao implements CorporateEventDao {
<emphasis role="bold">this.jdbcTemplate = new JdbcTemplate(dataSource);</emphasis>
}
<lineannotation>// JDBC-backed implementations of the methods on the <interfacename>CorporateEventDao</interfacename> follow...</lineannotation>
<lineannotation>// JDBC-backed implementations of the methods on the CorporateEventDao follow...</lineannotation>
}</programlisting></para>
<para>The corresponding XML configuration file <!--*corresponding* to what? TR: to the prvious code-snippet-->would
@@ -511,10 +515,10 @@ public class JdbcCorporateEventDao implements CorporateEventDao {
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
&lt;!-- Scans within the base package of the application for @Components to configure as beans --&gt;
&lt;context:component-scan base-package="org.springframework.docs.test" /&gt;
&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
&lt;property name="driverClassName" value="${jdbc.driverClassName}"/&gt;
&lt;property name="url" value="${jdbc.url}"/&gt;
@@ -545,7 +549,7 @@ public class JdbcCorporateEventDao implements CorporateEventDao {
</section>
</section>
<section id="jdbc-NamedParameterJdbcTemplate">
<section xml:id="jdbc-NamedParameterJdbcTemplate">
<title><classname>NamedParameterJdbcTemplate</classname></title>
<para>The <classname>NamedParameterJdbcTemplate</classname> class adds
@@ -614,8 +618,9 @@ public int countOfActorsByFirstName(String firstName) {
same Java package) is the <classname>SqlParameterSource</classname>
interface. You have already seen an example of an implementation of this
interface in one of the previous code snippet (the
<classname>MapSqlParameterSource</classname> class). <!--Revision ok?Why say *another feature*? So far this is the only feature discussed for NamedParameterJDBC template. It's mentioned above.--><!--In next paragraph you do describe another implementation. --><!--TR: Revised, please review.--><interfacename>An
<classname>SqlParameterSource</classname></interfacename> is a source of
<classname>MapSqlParameterSource</classname> class).
<!--Revision ok?Why say *another feature*? So far this is the only feature discussed for NamedParameterJDBC template. It's mentioned above.--><!--In next paragraph you do describe another implementation. --><!--TR: Revised, please review.-->
An <classname>SqlParameterSource</classname> is a source of
named parameter values to a
<classname>NamedParameterJdbcTemplate</classname>. The
<classname>MapSqlParameterSource</classname> class is a very simple
@@ -627,9 +632,9 @@ public int countOfActorsByFirstName(String firstName) {
implementation is the
<classname>BeanPropertySqlParameterSource</classname> class. This class
wraps an arbitrary JavaBean (that is, an instance of a class that
adheres to <ulink
url="http://java.sun.com/products/javabeans/docs/spec.html">the JavaBean
conventions</ulink>), and uses the properties of the wrapped JavaBean as
adheres to <link
xl:href="http://java.sun.com/products/javabeans/docs/spec.html">the JavaBean
conventions</link>), and uses the properties of the wrapped JavaBean as
the source of named parameter values.</para>
<programlisting language="java">public class Actor {
@@ -637,19 +642,19 @@ public int countOfActorsByFirstName(String firstName) {
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public Long getId() {
return this.id;
}
<lineannotation>// setters omitted...</lineannotation>
}</programlisting>
@@ -663,8 +668,8 @@ public void setDataSource(DataSource dataSource) {
public int countOfActors(Actor exampleActor) {
<lineannotation>// notice how the named parameters match the properties of the above '<classname>Actor</classname>' class</lineannotation>
String sql =
<lineannotation>// notice how the named parameters match the properties of the above 'Actor' class</lineannotation>
String sql =
"select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName";
SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
@@ -688,7 +693,7 @@ public int countOfActors(Actor exampleActor) {
of an application.</para>
</section>
<section id="jdbc-SimpleJdbcTemplate">
<section xml:id="jdbc-SimpleJdbcTemplate">
<title><classname>SimpleJdbcTemplate</classname></title>
<para>The <classname>SimpleJdbcTemplate</classname> class wraps the
@@ -713,7 +718,7 @@ public int countOfActors(Actor exampleActor) {
code snippet that does the same job with the
<classname>SimpleJdbcTemplate</classname>.</para>
<programlisting language="java"><lineannotation>// classic <classname>JdbcTemplate</classname>-style...</lineannotation>
<programlisting language="java"><lineannotation>// classic JdbcTemplate-style...</lineannotation>
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
@@ -722,9 +727,9 @@ public void setDataSource(DataSource dataSource) {
<!--How is the code shown below different from the code shown in the next example? It seems like they're the same.-->
public Actor findActor(String specialty, int age) {
String sql = "select id, first_name, last_name from T_ACTOR" +
String sql = "select id, first_name, last_name from T_ACTOR" +
" where specialty = ? and age = ?";
RowMapper&lt;Actor&gt; mapper = new RowMapper&lt;Actor&gt;() {
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
Actor actor = new Actor();
@@ -735,16 +740,16 @@ public Actor findActor(String specialty, int age) {
}
};
<lineannotation>// notice the wrapping up of the arguments in an array</lineannotation>
return (Actor) jdbcTemplate.queryForObject(sql, new Object[] {specialty, age}, mapper);
}</programlisting>
<para>Here is the same method, with the
<classname>SimpleJdbcTemplate</classname>.<!--The code shown above is the same as the code shown below. What is the difference?
<classname>SimpleJdbcTemplate</classname>.<!--The code shown above is the same as the code shown below. What is the difference?
TR: difference is in the way the parameters are passed in on the last line; no need to use an Objcet[].--></para>
<programlisting language="java"><lineannotation>// <classname>SimpleJdbcTemplate</classname>-style...</lineannotation>
<programlisting language="java"><lineannotation>// SimpleJdbcTemplate-style...</lineannotation>
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setDataSource(DataSource dataSource) {
@@ -753,9 +758,9 @@ public void setDataSource(DataSource dataSource) {
public Actor findActor(String specialty, int age) {
String sql = "select id, first_name, last_name from T_ACTOR" +
String sql = "select id, first_name, last_name from T_ACTOR" +
" where specialty = ? and age = ?";
RowMapper&lt;Actor&gt; mapper = new RowMapper&lt;Actor&gt;() {
RowMapper&lt;Actor&gt; mapper = new RowMapper&lt;Actor&gt;() {
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
Actor actor = new Actor();
actor.setId(rs.getLong("id"));
@@ -765,7 +770,7 @@ public Actor findActor(String specialty, int age) {
}
};
<lineannotation>// notice the use of varargs since the parameter values now come
<lineannotation>// notice the use of varargs since the parameter values now come
// after the RowMapper parameter</lineannotation>
return this.simpleJdbcTemplate.queryForObject(sql, mapper, specialty, age);
}</programlisting>
@@ -789,7 +794,7 @@ public Actor findActor(String specialty, int age) {
</note>
</section>
<section id="jdbc-SQLExceptionTranslator">
<section xml:id="jdbc-SQLExceptionTranslator">
<title><interfacename>SQLExceptionTranslator</interfacename></title>
<para><interfacename>SQLExceptionTranslator</interfacename> is an
@@ -891,29 +896,29 @@ public Actor findActor(String specialty, int age) {
<programlisting language="java"><lineannotation>private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
// create a <classname>JdbcTemplate</classname> and set data source</lineannotation>
this.jdbcTemplate = new JdbcTemplate();
this.jdbcTemplate.setDataSource(dataSource);
<lineannotation> // create a custom translator and set the <interfacename>DataSource</interfacename> for the default translation lookup</lineannotation>
CustomSQLErrorCodesTranslator tr = new CustomSQLErrorCodesTranslator();
tr.setDataSource(dataSource);
this.jdbcTemplate.setExceptionTranslator(tr);
// create a JdbcTemplate and set data source</lineannotation>
this.jdbcTemplate = new JdbcTemplate();
this.jdbcTemplate.setDataSource(dataSource);
<lineannotation> // create a custom translator and set the DataSource for the default translation lookup</lineannotation>
CustomSQLErrorCodesTranslator tr = new CustomSQLErrorCodesTranslator();
tr.setDataSource(dataSource);
this.jdbcTemplate.setExceptionTranslator(tr);
}
<lineannotation>public void updateShippingCharge(long orderId, long pct) {
// use the <classname>prepared JdbcTemplate</classname> for this <classname>update</classname></lineannotation>
// use the prepared JdbcTemplate for this update</lineannotation>
this.jdbcTemplate.update(
"update orders" +
" set shipping_charge = shipping_charge * ? / 100" +
"update orders" +
" set shipping_charge = shipping_charge * ? / 100" +
" where id = ?"
pct, orderId);
pct, orderId);
}</programlisting>
<para>The custom translator is passed a data source in order to look up
the error codes in <literal>sql-error-codes.xml</literal>.</para>
</section>
<section id="jdbc-statements-executing">
<section xml:id="jdbc-statements-executing">
<title>Executing statements</title>
<para>Executing an SQL statement requires very little code. You need a
@@ -941,7 +946,7 @@ public class ExecuteAStatement {
}</programlisting>
</section>
<section id="jdbc-statements-querying">
<section xml:id="jdbc-statements-querying">
<title>Running queries</title>
<para>Some query methods return a single value. To retrieve a count or a
@@ -966,7 +971,7 @@ public class RunAQuery {
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int getCount() {
return this.jdbcTemplate.queryForInt("select count(*) from mytable");
}
@@ -1005,7 +1010,7 @@ public List&lt;Map&lt;String, Object&gt;&gt; getList() {
<programlisting>[{name=Bob, id=1}, {name=Mary, id=2}]</programlisting>
</section>
<section id="jdbc-updates">
<section xml:id="jdbc-updates">
<title>Updating the database</title>
<para>The following example shows a column updated for a certain primary
@@ -1028,17 +1033,17 @@ public class ExecuteAnUpdate {
public void setName(int id, String name) {
this.jdbcTemplate.update(
"update mytable set name = ? where id = ?",
"update mytable set name = ? where id = ?",
name, id);
}
}</programlisting>
</section>
<section id="jdbc-auto-genereted-keys">
<section xml:id="jdbc-auto-genereted-keys">
<title>Retrieving auto-generated keys</title>
<para>An <methodname>update()</methodname> convenience method
supports<!--Give name of this method. Also indicate *what* is acquiring the primary keys. TR: Changed to *retrieval*.
supports<!--Give name of this method. Also indicate *what* is acquiring the primary keys. TR: Changed to *retrieval*.
The name of the method is *update*.--> the retrieval of primary keys generated
by the database. This support is part of the JDBC 3.0 standard; see
Chapter 13.6 of the specification for details. The method takes a
@@ -1070,10 +1075,10 @@ jdbcTemplate.update(
</section>
</section>
<section id="jdbc-connections">
<section xml:id="jdbc-connections">
<title>Controlling database connections</title>
<section id="jdbc-datasource">
<section xml:id="jdbc-datasource">
<title><interfacename>DataSource</interfacename><!--I don't understand why *DataSource* was a subsection of *Using the JDBC classes to control basic JDBC processing and error handling*.--><!--According to *The package hierarchy*section, there is a datasource package, separate from the core package.So I moved it to this section. TR: OK.--></title>
<para>Spring obtains a connection to the database through a
@@ -1137,7 +1142,7 @@ dataSource.setPassword("");</programlisting>
<para>DBCP configuration:</para>
<programlisting language="java">&lt;bean id="dataSource"
<programlisting language="java">&lt;bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
&lt;property name="driverClassName" value="${jdbc.driverClassName}"/&gt;
&lt;property name="url" value="${jdbc.url}"/&gt;
@@ -1160,7 +1165,7 @@ dataSource.setPassword("");</programlisting>
&lt;context:property-placeholder location="jdbc.properties"/&gt;</programlisting>
</section>
<section id="jdbc-DataSourceUtils">
<section xml:id="jdbc-DataSourceUtils">
<title><classname>DataSourceUtils</classname></title>
<para>The <classname>DataSourceUtils</classname> class is a convenient
@@ -1170,7 +1175,7 @@ dataSource.setPassword("");</programlisting>
<classname>DataSourceTransactionManager</classname>.</para>
</section>
<section id="jdbc-SmartDataSource">
<section xml:id="jdbc-SmartDataSource">
<title><interfacename>SmartDataSource</interfacename></title>
<para>The <interfacename>SmartDataSource</interfacename> interface
@@ -1182,11 +1187,11 @@ dataSource.setPassword("");</programlisting>
connection.</para>
</section>
<section id="jdbc-AbstractDataSource">
<section xml:id="jdbc-AbstractDataSource">
<title><classname>AbstractDataSource</classname></title>
<para><code><classname>AbstractDataSource</classname></code> is an
<literal><classname>abstract</classname></literal> base class for
<literal>abstract</literal> base class for
Spring's <interfacename>DataSource</interfacename> implementations that
implements code that is common to all <classname>DataSource</classname>
implementations.<!--Please revise *takes care of uninteresting glue* to specify what exactly it does. Avoid slang and idomatic language, --><!--especially important with non-native English readers. TR: Revised, please review.-->
@@ -1195,7 +1200,7 @@ dataSource.setPassword("");</programlisting>
implementation.<!--Preceding revision ok? If not, revise to specify *which* class you extend if you are writing your own DataSource imp. TR: OK.--></para>
</section>
<section id="jdbc-SingleConnectionDataSource">
<section xml:id="jdbc-SingleConnectionDataSource">
<title><classname>SingleConnectionDataSource</classname></title>
<para>The <classname>SingleConnectionDataSource</classname> class is an
@@ -1222,7 +1227,7 @@ dataSource.setPassword("");</programlisting>
connections.</para>
</section>
<section id="jdbc-DriverManagerDataSource">
<section xml:id="jdbc-DriverManagerDataSource">
<title><classname>DriverManagerDataSource</classname></title>
<para>The <classname>DriverManagerDataSource</classname> class is an
@@ -1244,7 +1249,7 @@ dataSource.setPassword("");</programlisting>
<classname>DriverManagerDataSource</classname>.</para>
</section>
<section id="jdbc-TransactionAwareDataSourceProxy">
<section xml:id="jdbc-TransactionAwareDataSourceProxy">
<title><classname>TransactionAwareDataSourceProxy</classname></title>
<para><classname>TransactionAwareDataSourceProxy</classname> is a proxy
@@ -1272,7 +1277,7 @@ dataSource.setPassword("");</programlisting>
details.)</emphasis></para>
</section>
<section id="jdbc-DataSourceTransactionManager">
<section xml:id="jdbc-DataSourceTransactionManager">
<title><classname>DataSourceTransactionManager</classname></title>
<para>The <classname>DataSourceTransactionManager</classname> class is a
@@ -1307,7 +1312,7 @@ dataSource.setPassword("");</programlisting>
isolation levels!</para>
</section>
<section id="jdbc-NativeJdbcExtractor">
<section xml:id="jdbc-NativeJdbcExtractor">
<title>NativeJdbcExtractor</title>
<para>Sometimes you need to access vendor specific JDBC methods that
@@ -1360,7 +1365,7 @@ dataSource.setPassword("");</programlisting>
</section>
</section>
<section id="jdbc-advanced-jdbc">
<section xml:id="jdbc-advanced-jdbc">
<title>JDBC batch operations</title>
<para>Most JDBC drivers provide improved performance if you batch multiple
@@ -1369,7 +1374,7 @@ dataSource.setPassword("");</programlisting>
processing using both the <classname>JdbcTemplate</classname> and the
<classname>SimpleJdbcTemplate</classname>.</para>
<section id="jdbc-batch-classic">
<section xml:id="jdbc-batch-classic">
<title>Basic batch operations with the JdbcTemplate</title>
<para>You accomplish <classname>JdbcTemplate</classname> batch
@@ -1419,7 +1424,7 @@ dataSource.setPassword("");</programlisting>
you to signal the end of the batch.</para>
</section>
<section id="jdbc-batch-list">
<section xml:id="jdbc-batch-list">
<title>Batch operations with a List of objects</title>
<para>Both the <classname>JdbcTemplate</classname> and the
@@ -1490,7 +1495,7 @@ dataSource.setPassword("");</programlisting>
driver returns a -2 value.</para>
</section>
<section id="jdbc-batch-multi">
<section xml:id="jdbc-batch-multi">
<title>Batch operations with multiple batches</title>
<para>The last example of a batch update deals with batches that are so
@@ -1525,7 +1530,7 @@ dataSource.setPassword("");</programlisting>
ps.setString(1, argument.getFirstName());
ps.setString(2, argument.getLastName());
ps.setLong(3, argument.getId().longValue());
}
} );
return updateCounts;
@@ -1545,7 +1550,7 @@ dataSource.setPassword("");</programlisting>
</section>
</section>
<section id="jdbc-simple-jdbc">
<section xml:id="jdbc-simple-jdbc">
<title>Simplifying JDBC operations with the SimpleJdbc classes</title>
<para>The <classname>SimpleJdbcInsert</classname> and
@@ -1555,14 +1560,14 @@ dataSource.setPassword("");</programlisting>
up front, although you can override or turn off the metadata processing if
you prefer to provide all the details in your code.</para>
<section id="jdbc-simple-jdbc-insert-1">
<section xml:id="jdbc-simple-jdbc-insert-1">
<title>Inserting data using SimpleJdbcInsert</title>
<para>Let's start by looking at the
<classname>SimpleJdbcInsert</classname> class with the minimal amount of
configuration options. You should instantiate the
<classname>SimpleJdbcInsert</classname> in the data access layer's
initialization method. <!--What do you mean *should be*? Are you saying a human should do it. If so, say *You should instantiate the SimpleJdbcInsert...* Also, is--><!--it correct to say *in* the data access layer's init method? Should it be *with*. Below, what do you mean by *fluid style*?
initialization method. <!--What do you mean *should be*? Are you saying a human should do it. If so, say *You should instantiate the SimpleJdbcInsert...* Also, is--><!--it correct to say *in* the data access layer's init method? Should it be *with*. Below, what do you mean by *fluid style*?
TR: Revised, please review.-->For this example, the initializing method is the
<classname>setDataSource</classname> method. You do not need to subclass
the <classname>SimpleJdbcInsert</classname> class; simply create a new
@@ -1579,7 +1584,7 @@ TR: Revised, please review.-->For this example, the initializing method is the
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
this.insertActor =
this.insertActor =
new SimpleJdbcInsert(dataSource).withTableName("t_actor");
}
@@ -1602,7 +1607,7 @@ TR: Revised, please review.-->For this example, the initializing method is the
statement.</para>
</section>
<section id="jdbc-simple-jdbc-insert-2">
<section xml:id="jdbc-simple-jdbc-insert-2">
<title>Retrieving auto-generated keys using SimpleJdbcInsert</title>
<para>This example uses the same insert as the preceding, but instead of
@@ -1646,7 +1651,7 @@ TR: Revised, please review.-->For this example, the initializing method is the
method.</para>
</section>
<section id="jdbc-simple-jdbc-insert-3">
<section xml:id="jdbc-simple-jdbc-insert-3">
<title>Specifying columns for a SimpleJdbcInsert</title>
<para>You can limit the columns for an insert by specifying a list of
@@ -1678,7 +1683,7 @@ TR: Revised, please review.-->For this example, the initializing method is the
on the metadata to determine which columns to use.</para>
</section>
<section id="jdbc-simple-jdbc-parameters">
<section xml:id="jdbc-simple-jdbc-parameters">
<title>Using SqlParameterSource to provide parameter values</title>
<para>Using a <classname>Map</classname> to provide parameter values
@@ -1741,7 +1746,7 @@ TR: Revised, please review.-->For this example, the initializing method is the
classes.</para>
</section>
<section id="jdbc-simple-jdbc-call-1">
<section xml:id="jdbc-simple-jdbc-call-1">
<title>Calling a stored procedure with SimpleJdbcCall</title>
<para>The <classname>SimpleJdbcCall</classname> class leverages metadata
@@ -1756,14 +1761,14 @@ TR: Revised, please review.-->For this example, the initializing method is the
<code>last_name</code>, and <code>birth_date</code> columns in the form
of <code>out</code> parameters.</para>
<para><programlisting>CREATE PROCEDURE read_actor (
IN in_id INTEGER,
OUT out_first_name VARCHAR(100),
OUT out_last_name VARCHAR(100),
OUT out_birth_date DATE)
BEGIN
SELECT first_name, last_name, birth_date
INTO out_first_name, out_last_name, out_birth_date
<para><programlisting>CREATE PROCEDURE read_actor (
IN in_id INTEGER,
OUT out_first_name VARCHAR(100),
OUT out_last_name VARCHAR(100),
OUT out_birth_date DATE)
BEGIN
SELECT first_name, last_name, birth_date
INTO out_first_name, out_last_name, out_birth_date
FROM t_actor where id = in_id;
END;</programlisting>The <code>in_id</code> parameter contains the
<code>id</code> of the actor you are looking up. The <code>out</code>
@@ -1793,7 +1798,7 @@ END;</programlisting>The <code>in_id</code> parameter contains the
public Actor readActor(Long id) {
SqlParameterSource in = new MapSqlParameterSource()
.addValue("in_id", id);
.addValue("in_id", id);
Map out = procReadActor.execute(in);
Actor actor = new Actor();
actor.setId(id);
@@ -1806,7 +1811,7 @@ END;</programlisting>The <code>in_id</code> parameter contains the
// ... additional methods
}</programlisting>The code you write for the execution of the call involves
creating an <classname>SqlParameterSource</classname> containing the IN
parameter. <!--sentence before this one said *all you need to specify* is name of procedure, but preceding sentence says it involves creating an--><!--SQLParameterSource. Isn't this *in addition* to specifying procedure name? Revise to clarify what a human does in this example. --><!--Reword preceding to clarify whether a human creates the SqlParameterSource.
parameter. <!--sentence before this one said *all you need to specify* is name of procedure, but preceding sentence says it involves creating an--><!--SQLParameterSource. Isn't this *in addition* to specifying procedure name? Revise to clarify what a human does in this example. --><!--Reword preceding to clarify whether a human creates the SqlParameterSource.
TR: Revised, please review. Execution is separate from declaration, so we still only need to declare the name of the proc.-->It's
important to match the name provided for the input value with that of
the parameter name <!--match *what* to the name of parameter in stored procedure?? And if this is something you're telling a human to do,--><!--reword to say *You must match <what> to the name of the parameter etc* TR: Revised.-->declared
@@ -1858,7 +1863,7 @@ TR: Revised, please review. Execution is separate from declaration, so we still
for the names of your returned <code>out</code> parameters.</para>
</section>
<section id="jdbc-simple-jdbc-call-2">
<section xml:id="jdbc-simple-jdbc-call-2">
<title>Explicitly declaring parameters to use for a
SimpleJdbcCall</title>
@@ -1919,7 +1924,7 @@ TR: Revised, please review. Execution is separate from declaration, so we still
metadata.</para>
</section>
<section id="jdbc-params">
<section xml:id="jdbc-params">
<title>How to define SqlParameters</title>
<para>To define a parameter for the SimpleJdbc classes and also for the
@@ -1965,7 +1970,7 @@ TR: Revised, please review. Execution is separate from declaration, so we still
define customized handling of the return values.</para>
</section>
<section id="jdbc-simple-jdbc-call-3">
<section xml:id="jdbc-simple-jdbc-call-3">
<title>Calling a stored function using SimpleJdbcCall</title>
<para>You call a stored function in almost the same way as you call a
@@ -1985,7 +1990,7 @@ TR: Revised, please review. Execution is separate from declaration, so we still
Here is the MySQL source for this function:</para>
<para><programlisting>CREATE FUNCTION get_actor_name (in_id INTEGER)
RETURNS VARCHAR(200) READS SQL DATA
RETURNS VARCHAR(200) READS SQL DATA
BEGIN
DECLARE out_name VARCHAR(200);
SELECT concat(first_name, ' ', last_name)
@@ -2013,7 +2018,7 @@ END;</programlisting></para>
public String getActorName(Long id) {
SqlParameterSource in = new MapSqlParameterSource()
.addValue("in_id", id);
.addValue("in_id", id);
String name = funcGetActorName.executeFunction(String.class, in);
return name;
}
@@ -2024,7 +2029,7 @@ END;</programlisting></para>
the function call.</para>
</section>
<section id="jdbc-simple-jdbc-call-4">
<section xml:id="jdbc-simple-jdbc-call-4">
<title>Returning ResultSet/REF Cursor from a SimpleJdbcCall</title>
<para>Calling a stored procedure or function that returns a result set
@@ -2083,7 +2088,7 @@ END;</programlisting>To call this procedure you declare the
</section>
</section>
<section id="jdbc-object">
<section xml:id="jdbc-object">
<title>Modeling JDBC operations as Java objects</title>
<para>The <literal>org.springframework.jdbc.object</literal> package
@@ -2108,7 +2113,7 @@ END;</programlisting>To call this procedure you declare the
operation classes, continue using these classes.</para>
</note>
<section id="jdbc-SqlQuery">
<section xml:id="jdbc-SqlQuery">
<title><classname>SqlQuery</classname></title>
<para><classname>SqlQuery</classname> is a reusable, threadsafe class
@@ -2126,7 +2131,7 @@ END;</programlisting>To call this procedure you declare the
<classname>UpdatableSqlQuery</classname>.</para>
</section>
<section id="jdbc-MappingSqlQuery">
<section xml:id="jdbc-MappingSqlQuery">
<title><classname>MappingSqlQuery</classname></title>
<para><classname>MappingSqlQuery</classname> is a reusable query in
@@ -2202,7 +2207,7 @@ public Customer getCustomer(Long id) {
}</programlisting>
</section>
<section id="jdbc-SqlUpdate">
<section xml:id="jdbc-SqlUpdate">
<title><classname>SqlUpdate</classname></title>
<para>The <classname>SqlUpdate</classname> class encapsulates an SQL
@@ -2247,7 +2252,7 @@ public class UpdateCreditRating extends SqlUpdate {
}</programlisting>
</section>
<section id="jdbc-StoredProcedure">
<section xml:id="jdbc-StoredProcedure">
<title><classname>StoredProcedure</classname></title>
<para>The <classname>StoredProcedure</classname> class is a superclass
@@ -2322,18 +2327,18 @@ import org.springframework.jdbc.object.StoredProcedure;
public class StoredProcedureDao {
private GetSysdateProcedure getSysdate;
@Autowired
public void init(DataSource dataSource) {
this.getSysdate = new GetSysdateProcedure(dataSource);
}
public Date getSysdate() {
return getSysdate.execute();
}
private class GetSysdateProcedure extends StoredProcedure {
private static final String SQL = "sysdate";
public GetSysdateProcedure(DataSource dataSource) {
@@ -2348,7 +2353,7 @@ public class StoredProcedureDao {
// the 'sysdate' sproc has no input parameters, so an empty Map is supplied...
Map&lt;String, Object&gt; results = execute(new HashMap&lt;String, Object&gt;());
Date sysdate = (Date) results.get("date");
return sysdate;
return sysdate;
}
}
@@ -2404,7 +2409,7 @@ import java.sql.SQLException;
import com.foo.domain.Title;
public final class TitleMapper implements RowMapper&lt;Title&gt; {
public Title mapRow(ResultSet rs, int rowNum) throws SQLException {
Title title = new Title();
title.setId(rs.getLong("id"));
@@ -2426,7 +2431,7 @@ import java.sql.SQLException;
import com.foo.domain.Genre;
public final class GenreMapper implements RowMapper&lt;Genre&gt; {
public Genre mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Genre(rs.getString("name"));
}
@@ -2472,13 +2477,13 @@ public class TitlesAfterDateStoredProcedure extends StoredProcedure {
</section>
</section>
<section id="jdbc-parameter-handling">
<section xml:id="jdbc-parameter-handling">
<title>Common problems with parameter and data value handling</title>
<para>Common problems with parameters and data values exist in the
different approaches provided by the Spring Framework JDBC.</para>
<section id="jdbc-type-information">
<section xml:id="jdbc-type-information">
<title>Providing SQL type information for parameters</title>
<para>Usually Spring determines the SQL type of the parameters based on
@@ -2522,7 +2527,7 @@ public class TitlesAfterDateStoredProcedure extends StoredProcedure {
</itemizedlist>
</section>
<section id="jdbc-lob">
<section xml:id="jdbc-lob">
<title>Handling BLOB and CLOB objects</title>
<para>You can store images, other binary objects, and large chunks of
@@ -2599,12 +2604,12 @@ final InputStream clobIs = new FileInputStream(clobIn);
final InputStreamReader clobReader = new InputStreamReader(clobIs);
jdbcTemplate.execute(
"INSERT INTO lob_table (id, a_clob, a_blob) VALUES (?, ?, ?)",
new AbstractLobCreatingPreparedStatementCallback(lobHandler) {]]><co id="lobHandler"/><![CDATA[
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
new AbstractLobCreatingPreparedStatementCallback(lobHandler) {]]><co xml:id="lobHandler"/><![CDATA[
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
throws SQLException {
ps.setLong(1, 1L);
lobCreator.setClobAsCharacterStream(ps, 2, clobReader, (int)clobIn.length());]]><co id="setClobAsCharacterStream"/><![CDATA[
lobCreator.setBlobAsBinaryStream(ps, 3, blobIs, (int)blobIn.length());]]><co id="setBlobAsBinaryStream"/><![CDATA[
lobCreator.setClobAsCharacterStream(ps, 2, clobReader, (int)clobIn.length());]]><co xml:id="setClobAsCharacterStream"/><![CDATA[
lobCreator.setBlobAsBinaryStream(ps, 3, blobIs, (int)blobIn.length());]]><co xml:id="setBlobAsBinaryStream"/><![CDATA[
}
}
);
@@ -2640,9 +2645,9 @@ clobReader.close();]]></programlisting>
new RowMapper<Map<String, Object>>() {
public Map<String, Object> mapRow(ResultSet rs, int i) throws SQLException {
Map<String, Object> results = new HashMap<String, Object>();
String clobText = lobHandler.getClobAsString(rs, "a_clob");]]><co id="getClobAsString"/><![CDATA[
String clobText = lobHandler.getClobAsString(rs, "a_clob");]]><co xml:id="getClobAsString"/><![CDATA[
results.put("CLOB", clobText);
byte[] blobBytes = lobHandler.getBlobAsBytes(rs, "a_blob");]]><co id="getBlobAsBytes"/><![CDATA[
byte[] blobBytes = lobHandler.getBlobAsBytes(rs, "a_blob");]]><co xml:id="getBlobAsBytes"/><![CDATA[
results.put("BLOB", blobBytes);
return results;
}
@@ -2662,7 +2667,7 @@ clobReader.close();]]></programlisting>
</para>
</section>
<section id="jdbc-in-clause">
<section xml:id="jdbc-in-clause">
<title>Passing in lists of values for IN clause</title>
<para>The SQL standard allows for selecting rows based on an expression
@@ -2696,7 +2701,7 @@ clobReader.close();]]></programlisting>
database supports this syntax.</para>
</section>
<section id="jdbc-complex-types">
<section xml:id="jdbc-complex-types">
<title>Handling complex types for stored procedure calls</title>
<para>When you call stored procedures you can sometimes use complex
@@ -2713,12 +2718,12 @@ clobReader.close();]]></programlisting>
that must be implemented. This interface is used as part of the
declaration of an <classname>SqlOutParameter</classname>.</para>
<para><programlisting language="java">final TestItem - new TestItem(123L, "A test item",
<para><programlisting language="java">final TestItem - new TestItem(123L, "A test item",
new SimpleDateFormat("yyyy-M-d").parse("2010-12-31"););
declareParameter(new SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE",
new SqlReturnType() {
public Object getTypeValue(CallableStatement cs, int colIndx, int sqlType, String typeName)
public Object getTypeValue(CallableStatement cs, int colIndx, int sqlType, String typeName)
throws SQLException {
STRUCT struct = (STRUCT)cs.getObject(colIndx);
Object[] attr = struct.getAttributes();
@@ -2738,7 +2743,7 @@ declareParameter(new SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE",
<classname>StructDescriptor</classname>s, as shown in the following
example, or <classname>ArrayDescriptor</classname>s.<!--Rewording of preceding ok? The example is showing human participation, I assume. ;-) TR: Yes :), OK.--></para>
<para><programlisting language="java">final TestItem - new TestItem(123L, "A test item",
<para><programlisting language="java">final TestItem - new TestItem(123L, "A test item",
new SimpleDateFormat("yyyy-M-d").parse("2010-12-31"););
SqlTypeValue value = new AbstractSqlTypeValue() {
@@ -2775,18 +2780,18 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
</section>
</section>
<section id="jdbc-embedded-database-support">
<section xml:id="jdbc-embedded-database-support">
<title>Embedded database support</title>
<para>The <literal>org.springframework.jdbc.datasource.embedded</literal>
package provides support for embedded Java database engines. Support for
<ulink url="http://www.hsqldb.org">HSQL</ulink>, <ulink
url="http://www.h2database.com">H2</ulink>, and <ulink
url="http://db.apache.org/derby">Derby</ulink> is provided natively. You
<link xl:href="http://www.hsqldb.org">HSQL</link>, <link
xl:href="http://www.h2database.com">H2</link>, and <link
xl:href="http://db.apache.org/derby">Derby</link> is provided natively. You
can also use an extensible API to plug in new embedded database types and
<classname>DataSource</classname> implementations.</para>
<section id="jdbc-why-embedded-database">
<section xml:id="jdbc-why-embedded-database">
<title>Why use an embedded database?</title>
<para>An embedded database is useful during the development phase of a
@@ -2795,7 +2800,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
rapidly evolve SQL during development.</para>
</section>
<section id="jdbc-embedded-database-xml">
<section xml:id="jdbc-embedded-database-xml">
<title>Creating an embedded database instance using Spring XML</title>
<para>If you want to expose an embedded database instance as a bean in a
@@ -2814,7 +2819,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
needed.</para>
</section>
<section id="jdbc-embedded-database-java">
<section xml:id="jdbc-embedded-database-java">
<title>Creating an embedded database instance programmatically</title>
<para>The <classname>EmbeddedDatabaseBuilder</classname> class provides
@@ -2828,7 +2833,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
</programlisting></para>
</section>
<section id="jdbc-embedded-database-extension">
<section xml:id="jdbc-embedded-database-extension">
<title>Extending the embedded database support</title>
<para>Spring JDBC embedded database support can be extended in two ways:
@@ -2847,11 +2852,11 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
</orderedlist></para>
<para>You are encouraged to contribute back extensions to the Spring
community at <ulink
url="jira.springframework.org">jira.springframework.org</ulink>.</para>
community at <link
xl:href="jira.springframework.org">jira.springframework.org</link>.</para>
</section>
<section id="jdbc-embedded-database-using-HSQL">
<section xml:id="jdbc-embedded-database-using-HSQL">
<title>Using HSQL</title>
<para>Spring supports HSQL 1.8.0 and above. HSQL is the default embedded
@@ -2863,7 +2868,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
<literal>EmbeddedDatabaseType.HSQL</literal>.</para>
</section>
<section id="jdbc-embedded-database-using-H2">
<section xml:id="jdbc-embedded-database-using-H2">
<title>Using H2</title>
<para>Spring supports the H2 database as well. To enable H2, set the
@@ -2874,7 +2879,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
<literal>EmbeddedDatabaseType.H2</literal>.</para>
</section>
<section id="jdbc-embedded-database-using-Derby">
<section xml:id="jdbc-embedded-database-using-Derby">
<title>Using Derby</title>
<para>Spring also supports Apache Derby 10.5 and above. To enable Derby,
@@ -2885,7 +2890,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
<literal>EmbeddedDatabaseType.Derby</literal>.</para>
</section>
<section id="jdbc-embedded-database-dao-testing">
<section xml:id="jdbc-embedded-database-dao-testing">
<title>Testing data access logic with an embedded database</title>
<para>Embedded databases provide a lightweight way to test data access
@@ -2896,12 +2901,12 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
public class DataAccessUnitTestTemplate {
private EmbeddedDatabase db;
@Before
public void setUp() {
// creates an HSQL in-memory database populated from default scripts
// classpath:schema.sql and classpath:data.sql
db = new EmbeddedDatabaseBuilder().addDefaultScripts().build();
db = new EmbeddedDatabaseBuilder().addDefaultScripts().build();
}
@Test
@@ -2919,7 +2924,7 @@ public class DataAccessUnitTestTemplate {
</section>
</section>
<section id="jdbc-intializing-datasource">
<section xml:id="jdbc-intializing-datasource">
<title>Initializing a DataSource</title>
<para>The <literal>org.springframework.jdbc.datasource.init</literal>
@@ -2929,7 +2934,7 @@ public class DataAccessUnitTestTemplate {
<classname>DataSource</classname> for an application, but sometimes you
need to initialize an instance running on a server somewhere.</para>
<section id="jdbc-initializing-datasource-xml">
<section xml:id="jdbc-initializing-datasource-xml">
<title>Initializing a database instance using Spring XML</title>
<para>If you want to initialize a database and you can provide a
@@ -2993,7 +2998,7 @@ public class DataAccessUnitTestTemplate {
can simply use the <classname>DataSourceInitializer</classname>
directly, and define it as a component in your application.</para>
<section id="jdbc-client-component-initialization">
<section xml:id="jdbc-client-component-initialization">
<title>Initialization of Other Components that Depend on the
Database</title>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="jms"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="jms">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>JMS (Java Message Service)</title>
<section id="jms-introduction">
<section xml:id="jms-introduction">
<title>Introduction</title>
<para>Spring provides a JMS integration framework that simplifies the use
@@ -60,10 +64,10 @@
Spring's transaction management mechanisms.</para>
</section>
<section id="jms-using">
<section xml:id="jms-using">
<title>Using Spring JMS</title>
<section id="jms-jmstemplate">
<section xml:id="jms-jmstemplate">
<title><classname>JmsTemplate</classname></title>
<para>The <classname>JmsTemplate</classname> class is the central class
@@ -118,7 +122,7 @@
</note>
</section>
<section id="jms-connections">
<section xml:id="jms-connections">
<title>Connections</title>
<para>The <classname>JmsTemplate</classname> requires a reference to a
@@ -140,7 +144,7 @@
should ensure that it references the managed implementation of the
<classname>ConnectionFactory</classname>.</para>
<section id="jms-caching-resources">
<section xml:id="jms-caching-resources">
<title>Caching Messaging Resources</title>
<para>The standard API involves creating many intermediate objects. To
@@ -154,7 +158,7 @@
IConnectionFactory are provided.</para>
</section>
<section id="jms-connection-factory">
<section xml:id="jms-connection-factory">
<title>SingleConnectionFactory</title>
<para>Spring provides an implementation of the
@@ -171,7 +175,7 @@
from JNDI.</para>
</section>
<section id="jdbc-connection-factory-caching">
<section xml:id="jdbc-connection-factory-caching">
<title>CachingConnectionFactory</title>
<para>The <classname>CachingConnectionFactory</classname> extends the
@@ -193,7 +197,7 @@
</section>
</section>
<section id="jms-destinations">
<section xml:id="jms-destinations">
<title>Destination Management</title>
<para>Destinations, like ConnectionFactories, are JMS administered
@@ -255,7 +259,7 @@
destination.</para>
</section>
<section id="jms-mdp">
<section xml:id="jms-mdp">
<title>Message Listener Containers</title>
<para>One of the most common uses of JMS messages in the EJB world is to
@@ -279,7 +283,7 @@
<para>There are two standard JMS message listener containers packaged
with Spring, each with its specialised feature set.</para>
<section id="jms-mdp-simple">
<section xml:id="jms-mdp-simple">
<title>SimpleMessageListenerContainer</title>
<para>This message listener container is the simpler of the two
@@ -293,7 +297,7 @@
- but is generally not compatible with Java EE's JMS restrictions.</para>
</section>
<section id="jms-mdp-default">
<section xml:id="jms-mdp-default">
<title>DefaultMessageListenerContainer</title>
<para>This message listener container is the one used in most cases.
@@ -309,7 +313,7 @@
</section>
</section>
<section id="jms-tx">
<section xml:id="jms-tx">
<title>Transaction management</title>
<para>Spring provides a <classname>JmsTransactionManager</classname>
@@ -358,7 +362,7 @@
</section>
</section>
<section id="jms-sending">
<section xml:id="jms-sending">
<title>Sending a <interfacename>Message</interfacename></title>
<para>The <classname>JmsTemplate</classname> contains many convenience
@@ -420,7 +424,7 @@ public class JmsQueueSender {
a default destination, the <methodname>send(MessageCreator c)</methodname>
sends a message to that destination.</para>
<section id="jms-msg-conversion">
<section xml:id="jms-msg-conversion">
<title>Using Message Converters</title>
<para>In order to facilitate the sending of domain model objects, the
@@ -485,11 +489,11 @@ public class JmsQueueSender {
Fields={
Name={String:Mark}
Age={Integer:47}
}
}
}</programlisting>
</section>
<section id="jms-callbacks">
<section xml:id="jms-callbacks">
<title><interfacename>SessionCallback</interfacename> and
<interfacename>ProducerCallback</interfacename></title>
@@ -508,10 +512,10 @@ public class JmsQueueSender {
</section>
</section>
<section id="jms-receiving">
<section xml:id="jms-receiving">
<title>Receiving a message</title>
<section id="jms-receiving-sync">
<section xml:id="jms-receiving-sync">
<title>Synchronous Reception</title>
<para>While JMS is typically associated with asynchronous processing, it
@@ -524,7 +528,7 @@ public class JmsQueueSender {
should wait before giving up waiting for a message.</para>
</section>
<section id="jms-asynchronousMessageReception">
<section xml:id="jms-asynchronousMessageReception">
<title>Asynchronous Reception - Message-Driven POJOs</title>
<para>In a fashion similar to a Message-Driven Bean (MDB) in the EJB
@@ -584,7 +588,7 @@ public class ExampleListener implements MessageListener {
implementation.</para>
</section>
<section id="jms-receiving-async-session-aware-message-listener">
<section xml:id="jms-receiving-async-session-aware-message-listener">
<title>The <interfacename>SessionAwareMessageListener</interfacename>
interface</title>
@@ -627,7 +631,7 @@ public interface SessionAwareMessageListener {
exceptions thrown.</para>
</section>
<section id="jms-receiving-async-message-listener-adapter">
<section xml:id="jms-receiving-async-message-listener-adapter">
<title>The <classname>MessageListenerAdapter</classname></title>
<para>The <classname>MessageListenerAdapter</classname> class is the
@@ -709,7 +713,7 @@ public interface SessionAwareMessageListener {
&lt;bean class="jmsexample.DefaultTextMessageDelegate"/&gt;
&lt;/constructor-arg&gt;
&lt;property name="defaultListenerMethod" value="receive"/&gt;
<lineannotation>&lt;!-- we <emphasis role="bold">don't</emphasis> want automatic message context extraction --&gt;</lineannotation>
<lineannotation>&lt;!-- we don't want automatic message context extraction --&gt;</lineannotation>
&lt;property name="messageConverter"&gt;
&lt;null/&gt;
&lt;/property&gt;
@@ -727,7 +731,7 @@ public interface SessionAwareMessageListener {
<programlisting language="java">public interface ResponsiveTextMessageDelegate {
<lineannotation><emphasis role="bold">// notice the return type...</emphasis></lineannotation>
<lineannotation>// notice the return type...</lineannotation>
String receive(TextMessage message);
}</programlisting>
@@ -755,7 +759,7 @@ public interface SessionAwareMessageListener {
the call stack).</para>
</section>
<section id="jms-tx-participation">
<section xml:id="jms-tx-participation">
<title>Processing messages within transactions</title>
<para>Invoking a message listener within a transaction only requires
@@ -811,7 +815,7 @@ public interface SessionAwareMessageListener {
</section>
</section>
<section id="jms-jca-message-endpoint-manager">
<section xml:id="jms-jca-message-endpoint-manager">
<title>Support for JCA Message Endpoints</title>
<para>Beginning with version 2.5, Spring also provides support for a
@@ -906,7 +910,7 @@ public interface SessionAwareMessageListener {
</note>
</section>
<section id="jms-namespace">
<section xml:id="jms-namespace">
<title>JMS Namespace Support</title>
<para>Spring 2.5 introduces an XML namespace for simplifying JMS
@@ -921,7 +925,7 @@ public interface SessionAwareMessageListener {
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
<emphasis role="bold">http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd"</emphasis>&gt;
<lineannotation>&lt;!-- <literal>&lt;bean/&gt;</literal> definitions here --&gt;</lineannotation>
<lineannotation>&lt;!-- &lt;bean/&gt; definitions here --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
@@ -947,7 +951,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
may contain several optional ones. The following table describes all available
attributes:</para>
<table id="jms-namespace-listener-tbl">
<table xml:id="jms-namespace-listener-tbl">
<title>Attributes of the JMS <literal>&lt;listener&gt;</literal>
element</title>
@@ -1054,7 +1058,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
provides a discussion of transaction choices and message redelivery
scenarios.</para>
<table id="jms-namespace-listener-container-tbl">
<table xml:id="jms-namespace-listener-container-tbl">
<title>Attributes of the JMS
<literal>&lt;listener-container&gt;</literal> element</title>
@@ -1210,7 +1214,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<para>The available configuration options for the JCA variant are
described in the following table:</para>
<table id="jms-namespace-jca-listener-container-tbl">
<table xml:id="jms-namespace-jca-listener-container-tbl">
<title>Attributes of the JMS
<literal>&lt;jca-listener-container/&gt;</literal> element</title>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="jmx"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="jmx">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>JMX</title>
<section id="jmx-introduction">
<section xml:id="jmx-introduction">
<title>Introduction</title>
<para>The JMX support in Spring provides you with the features to easily
@@ -53,7 +57,7 @@
features.</para>
</section>
<section id="jmx-exporting">
<section xml:id="jmx-exporting">
<title>Exporting your beans to JMX</title>
<para>The core class in Spring's JMX framework is the
@@ -77,7 +81,7 @@ public class JmxTestBean implements IJmxTestBean {
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@@ -102,7 +106,7 @@ public class JmxTestBean implements IJmxTestBean {
<programlisting language="xml"><![CDATA[<beans>
]]><lineannotation>&lt;!-- this bean must <emphasis role="bold">not</emphasis> be lazily initialized if the exporting is to happen --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- this bean must not be lazily initialized if the exporting is to happen --&gt;</lineannotation><![CDATA[
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"]]> <emphasis
role="bold">lazy-init="false"</emphasis><![CDATA[>
<property name="beans">
@@ -137,7 +141,7 @@ public class JmxTestBean implements IJmxTestBean {
inherited from the <classname>Object</classname> class) are exposed as
operations.</para>
<section id="jmx-exporting-mbeanserver">
<section xml:id="jmx-exporting-mbeanserver">
<title>Creating an <interfacename>MBeanServer</interfacename></title>
<para>The above configuration assumes that the application is running in
@@ -167,7 +171,7 @@ public class JmxTestBean implements IJmxTestBean {
]]><lineannotation>&lt;!--
this bean needs to be eagerly pre-instantiated in order for the exporting to occur;
this means that it must <emphasis role="bold">not</emphasis> be marked as lazily initialized
this means that it must not be marked as lazily initialized
--&gt;</lineannotation><![CDATA[
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
@@ -195,7 +199,7 @@ public class JmxTestBean implements IJmxTestBean {
you must (of course) have a JMX implementation on your classpath.</para>
</section>
<section id="jmx-mbean-server">
<section xml:id="jmx-mbean-server">
<title>Reusing an existing <interfacename>MBeanServer</interfacename></title>
<para>If no server is specified, the <classname>MBeanExporter</classname>
@@ -210,10 +214,10 @@ public class JmxTestBean implements IJmxTestBean {
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
]]><lineannotation>&lt;!-- indicate to first look for a server --&gt;</lineannotation><![CDATA[
<property name="locateExistingServerIfPossible" value="true"/>
]]><lineannotation>&lt;!-- search for the <interfacename>MBeanServer</interfacename> instance with the given agentId --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- search for the MBeanServer instance with the given agentId --&gt;</lineannotation><![CDATA[
<property name="agentId" value="]]><emphasis><![CDATA[<MBeanServer instance agentId>]]></emphasis><![CDATA["/>
</bean>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="server" ref="mbeanServer"/>
...
@@ -227,17 +231,17 @@ public class JmxTestBean implements IJmxTestBean {
<programlisting language="xml"><![CDATA[<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="server">
]]><lineannotation>&lt;!-- Custom <literal>MBeanServerLocator</literal> --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- Custom MBeanServerLocator --&gt;</lineannotation><![CDATA[
<bean class="platform.package.MBeanServerLocator" factory-method="locateMBeanServer"/>
</property>
]]><lineannotation>&lt;!-- other beans here --&gt;</lineannotation><![CDATA[
</bean>
</beans>]]></programlisting>
</section>
<section id="jmx-exporting-lazy">
<section xml:id="jmx-exporting-lazy">
<title>Lazy-initialized MBeans</title>
<para>If you configure a bean with the
@@ -249,7 +253,7 @@ public class JmxTestBean implements IJmxTestBean {
from the container until the first invocation on the proxy occurs.</para>
</section>
<section id="jmx-exporting-auto">
<section xml:id="jmx-exporting-auto">
<title>Automatic registration of MBeans</title>
<para>Any beans that are exported through the
@@ -272,7 +276,7 @@ public class JmxTestBean implements IJmxTestBean {
behavior can be overridden as detailed in <xref linkend="jmx-naming" />.</para>
</section>
<section id="jmx-exporting-registration-behavior">
<section xml:id="jmx-exporting-registration-behavior">
<title>Controlling the registration behavior</title>
<para>Consider the scenario where a Spring
@@ -294,7 +298,7 @@ public class JmxTestBean implements IJmxTestBean {
<classname>ObjectName</classname>; these registration behaviors are
summarized on the following table:</para>
<table id="jmx-registration-behaviors">
<table xml:id="jmx-registration-behaviors">
<title>Registration Behaviors</title>
<tgroup cols="2">
@@ -390,7 +394,7 @@ public class JmxTestBean implements IJmxTestBean {
</section>
</section>
<section id="jmx-interface">
<section xml:id="jmx-interface">
<title>Controlling the management interface of your beans</title>
<para>In the previous example, you had little control over the management
@@ -402,7 +406,7 @@ public class JmxTestBean implements IJmxTestBean {
Spring JMX provides a comprehensive and extensible mechanism for
controlling the management interfaces of your beans.</para>
<section id="jmx-interface-assembler">
<section xml:id="jmx-interface-assembler">
<title>The <interfacename>MBeanInfoAssembler</interfacename>
Interface</title>
@@ -420,7 +424,7 @@ public class JmxTestBean implements IJmxTestBean {
source-level metadata or any arbitrary interface.</para>
</section>
<section id="jmx-interface-metadata">
<section xml:id="jmx-interface-metadata">
<title>Using Source-Level Metadata (JDK 5.0 annotations)</title>
<para>Using the <classname>MetadataMBeanInfoAssembler</classname> you
@@ -443,7 +447,7 @@ public class JmxTestBean implements IJmxTestBean {
setter to create a write-only or read-only attribute
respectively.</para>
<para>The example below shows the annotated version of the
<para>The example below shows the annotated version of the
<classname>JmxTestBean</classname> class that you saw earlier:</para>
<programlisting language="java"><![CDATA[package org.springframework.jmx;
@@ -537,7 +541,7 @@ public class AnnotationTestBean implements IJmxTestBean {
<property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
]]><lineannotation>&lt;!-- will pick up the <classname>ObjectName</classname> from the annotation --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- will pick up the ObjectName from the annotation --&gt;</lineannotation><![CDATA[
<bean id="namingStrategy"
class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource"/>
@@ -548,7 +552,7 @@ public class AnnotationTestBean implements IJmxTestBean {
<property name="age" value="100"/>
</bean>
</beans>]]></programlisting>
<para>Here you can see that an
<classname>MetadataMBeanInfoAssembler</classname> bean has been
@@ -559,13 +563,13 @@ public class AnnotationTestBean implements IJmxTestBean {
management interfaces for your Spring-exposed MBeans.</para>
</section>
<section id="jmx-interface-metadata-types">
<section xml:id="jmx-interface-metadata-types">
<title>Source-Level Metadata Types</title>
<para>The following source level metadata types are available for use in
Spring JMX:</para>
<para><table id="jmx-metadata-types">
<para><table xml:id="jmx-metadata-types">
<title>Source-Level Metadata Types</title>
<tgroup cols="3">
@@ -627,7 +631,7 @@ public class AnnotationTestBean implements IJmxTestBean {
<para>The following configuration parameters are available for use on
these source-level metadata types:</para>
<para><table id="jmx-metadata-parameters">
<para><table xml:id="jmx-metadata-parameters">
<title>Source-Level Metadata Parameters</title>
<tgroup cols="3">
@@ -763,7 +767,7 @@ public class AnnotationTestBean implements IJmxTestBean {
</table></para>
</section>
<section id="jmx-interface-autodetect">
<section xml:id="jmx-interface-autodetect">
<title>The <classname>AutodetectCapableMBeanInfoAssembler</classname>
interface</title>
@@ -787,7 +791,7 @@ public class AnnotationTestBean implements IJmxTestBean {
<programlisting language="xml"><![CDATA[<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
]]><lineannotation>&lt;!-- notice how no <literal>'beans'</literal> are explicitly configured here --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- notice how no 'beans' are explicitly configured here --&gt;</lineannotation><![CDATA[
<property name="autodetect" value="true"/>
<property name="assembler" ref="assembler"/>
</bean>
@@ -817,7 +821,7 @@ public class AnnotationTestBean implements IJmxTestBean {
<xref linkend="jmx-naming" />.</para>
</section>
<section id="jmx-interface-java">
<section xml:id="jmx-interface-java">
<title>Defining management interfaces using Java interfaces</title>
<para>In addition to the
@@ -908,7 +912,7 @@ public class AnnotationTestBean implements IJmxTestBean {
create the management interface.</para>
</section>
<section id="jmx-interface-methodnames">
<section xml:id="jmx-interface-methodnames">
<title>Using
<classname>MethodNameBasedMBeanInfoAssembler</classname></title>
@@ -944,7 +948,7 @@ public class AnnotationTestBean implements IJmxTestBean {
</section>
</section>
<section id="jmx-naming">
<section xml:id="jmx-naming">
<title>Controlling the <classname>ObjectName</classname>s for your beans</title>
<para>Behind the scenes, the <classname>MBeanExporter</classname>
@@ -966,7 +970,7 @@ public class AnnotationTestBean implements IJmxTestBean {
and the <classname>MetadataNamingStrategy</classname> that uses source
level metadata to obtain the <classname>ObjectName</classname>.</para>
<section id="jmx-naming-properties">
<section xml:id="jmx-naming-properties">
<title>Reading <classname>ObjectName</classname>s from <classname>Properties</classname></title>
<para>You can configure your own
@@ -1026,7 +1030,7 @@ public class AnnotationTestBean implements IJmxTestBean {
<classname>ObjectName</classname>.</para>
</section>
<section id="jmx-naming-metadata">
<section xml:id="jmx-naming-metadata">
<title>Using the <classname>MetadataNamingStrategy</classname></title>
<para>The <classname>MetadataNamingStrategy</classname> uses
@@ -1074,7 +1078,7 @@ public class AnnotationTestBean implements IJmxTestBean {
</section>
<section id="jmx-context-mbeanexport">
<section xml:id="jmx-context-mbeanexport">
<title>Configuring annotation based MBean export</title>
<para>If you prefer using <link linkend="jmx-interface-metadata">the annotation based
approach</link> to define your management interfaces, then a convenience subclass of
@@ -1129,7 +1133,7 @@ ContextConfiguration {
</section>
</section>
<section id="jmx-jsr160">
<section xml:id="jmx-jsr160">
<title>JSR-160 Connectors</title>
<para>For remote access, Spring JMX module offers two
@@ -1137,7 +1141,7 @@ ContextConfiguration {
<literal>org.springframework.jmx.support</literal> package for creating
both server- and client-side connectors.</para>
<section id="jmx-jsr160-server">
<section xml:id="jmx-jsr160-server">
<title>Server-side Connectors</title>
<para>To have Spring JMX create, start and expose a JSR-160
@@ -1164,7 +1168,7 @@ ContextConfiguration {
<programlisting language="xml"><![CDATA[<bean id="serverConnector"
class="org.springframework.jmx.support.ConnectorServerFactoryBean">
<property name="objectName" value="connector:name=rmi"/>
<property name="serviceUrl"
<property name="serviceUrl"
value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/myconnector"/>
</bean>]]></programlisting>
@@ -1179,7 +1183,7 @@ ContextConfiguration {
<programlisting language="xml"><![CDATA[<bean id="serverConnector"
class="org.springframework.jmx.support.ConnectorServerFactoryBean">
<property name="objectName" value="connector:name=iiop"/>
<property name="serviceUrl"
<property name="serviceUrl"
value="service:jmx:iiop://localhost/jndi/iiop://localhost:900/myconnector"/>
<property name="threaded" value="true"/>
<property name="daemon" value="true"/>
@@ -1202,7 +1206,7 @@ ContextConfiguration {
</bean>]]></programlisting>
</section>
<section id="jmx-jsr160-client">
<section xml:id="jmx-jsr160-client">
<title>Client-side Connectors</title>
<para>To create an <classname>MBeanServerConnection</classname> to a
@@ -1215,15 +1219,15 @@ ContextConfiguration {
</bean>]]></programlisting>
</section>
<section id="jmx-jsr160-protocols">
<section xml:id="jmx-jsr160-protocols">
<title>JMX over Burlap/Hessian/SOAP</title>
<para>JSR-160 permits extensions to the way in which communication is
done between the client and the server. The examples above are using the
mandatory RMI-based implementation required by the JSR-160 specification
(IIOP and JRMP) and the (optional) JMXMP. By using other providers or
JMX implementations (such as <ulink
url="http://mx4j.sourceforge.net">MX4J</ulink>) you can take advantage
JMX implementations (such as <link
xl:href="http://mx4j.sourceforge.net">MX4J</link>) you can take advantage
of protocols like SOAP, Hessian, Burlap over simple HTTP or SSL and
others:</para>
@@ -1237,7 +1241,7 @@ ContextConfiguration {
</section>
</section>
<section id="jmx-proxy">
<section xml:id="jmx-proxy">
<title>Accessing MBeans via Proxies</title>
<para>Spring JMX allows you to create proxies that re-route calls to
@@ -1290,13 +1294,13 @@ ContextConfiguration {
<classname>MBeanServerConnection</classname>.</para>
</section>
<section id="jmx-notifications">
<section xml:id="jmx-notifications">
<title>Notifications</title>
<para>Spring's JMX offering includes comprehensive support for JMX
notifications.</para>
<section id="jmx-notifications-listeners">
<section xml:id="jmx-notifications-listeners">
<title>Registering Listeners for Notifications</title>
<para>Spring's JMX support makes it very easy to register any number of
@@ -1304,8 +1308,8 @@ ContextConfiguration {
(this includes MBeans exported by Spring's
<classname>MBeanExporter</classname> and MBeans registered via some
other mechanism). By way of an example, consider the scenario where one
would like to be informed (via a <classname>Notification</classname>)
each and every time an attribute of a target MBean changes.</para>
would like to be informed (via a <classname>Notification</classname>)
each and every time an attribute of a target MBean changes.</para>
<programlisting language="java"><![CDATA[package com.example;
@@ -1351,20 +1355,20 @@ public class ConsoleLoggingNotificationListener
</beans>]]></programlisting>
<para>With the above configuration in place, every time a JMX
<classname>Notification</classname> is broadcast from the target MBean
(<literal>bean:name=testBean1</literal>), the
<classname>ConsoleLoggingNotificationListener</classname> bean that was
registered as a listener via the
<literal>notificationListenerMappings</literal> property will be
notified. The <classname>ConsoleLoggingNotificationListener</classname>
bean can then take whatever action it deems appropriate in response to
the <classname>Notification</classname>.</para>
<para>With the above configuration in place, every time a JMX
<classname>Notification</classname> is broadcast from the target MBean
(<literal>bean:name=testBean1</literal>), the
<classname>ConsoleLoggingNotificationListener</classname> bean that was
registered as a listener via the
<literal>notificationListenerMappings</literal> property will be
notified. The <classname>ConsoleLoggingNotificationListener</classname>
bean can then take whatever action it deems appropriate in response to
the <classname>Notification</classname>.</para>
<para>You can also use straight bean names as the link between exported beans
and listeners:</para>
<para>You can also use straight bean names as the link between exported beans
and listeners:</para>
<programlisting language="xml"><![CDATA[<beans>
<programlisting language="xml"><![CDATA[<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
@@ -1388,13 +1392,13 @@ public class ConsoleLoggingNotificationListener
</beans>]]></programlisting>
<para>If one wants to register a single <classname>NotificationListener</classname>
instance for all of the beans that the enclosing <classname>MBeanExporter</classname>
is exporting, one can use the special wildcard <literal>'*'</literal> (sans quotes)
as the key for an entry in the <literal>notificationListenerMappings</literal>
property map; for example:</para>
<para>If one wants to register a single <classname>NotificationListener</classname>
instance for all of the beans that the enclosing <classname>MBeanExporter</classname>
is exporting, one can use the special wildcard <literal>'*'</literal> (sans quotes)
as the key for an entry in the <literal>notificationListenerMappings</literal>
property map; for example:</para>
<programlisting language="xml"><![CDATA[<property name="notificationListenerMappings">
<programlisting language="xml"><![CDATA[<property name="notificationListenerMappings">
<map>
<entry key="*">
<bean class="com.example.ConsoleLoggingNotificationListener"/>
@@ -1494,7 +1498,7 @@ public class ConsoleLoggingNotificationListener
</list>
</property>
</bean>
]]><lineannotation>&lt;!-- implements both the <interfacename>NotificationListener</interfacename> and <interfacename>NotificationFilter</interfacename> interfaces --&gt;</lineannotation><![CDATA[
<bean id="customerNotificationListener" class="com.example.ConsoleLoggingNotificationListener"/>
@@ -1511,7 +1515,7 @@ public class ConsoleLoggingNotificationListener
</beans>]]></programlisting>
</section>
<section id="jmx-notifications-publishing">
<section xml:id="jmx-notifications-publishing">
<title>Publishing Notifications</title>
<para>Spring provides support not just for registering to receive
@@ -1568,7 +1572,7 @@ public class ConsoleLoggingNotificationListener
<literal>add(int, int)</literal> operation is invoked.</para>
<programlisting language="java"><![CDATA[package org.springframework.jmx;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.jmx.export.notification.NotificationPublisher;
import javax.management.Notification;
@@ -1591,7 +1595,7 @@ public class JmxTestBean implements IJmxTestBean, NotificationPublisherAware {
public void dontExposeMe() {
throw new RuntimeException();
}
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
this.publisher = notificationPublisher;
}
@@ -1599,39 +1603,39 @@ public class JmxTestBean implements IJmxTestBean, NotificationPublisherAware {
<para>The <classname>NotificationPublisher</classname> interface and the
machinery to get it all working is one of the nicer features of Spring's JMX support.
It does however come with the price tag of coupling your classes to both Spring and JMX; as
always, the advice here is to be pragmatic... if you need the functionality offered by the
It does however come with the price tag of coupling your classes to both Spring and JMX; as
always, the advice here is to be pragmatic... if you need the functionality offered by the
<classname>NotificationPublisher</classname> and you can accept the coupling to both Spring
and JMX, then do so.</para>
and JMX, then do so.</para>
</section>
</section>
<section id="jmx-resources">
<section xml:id="jmx-resources">
<title>Further Resources</title>
<para>This section contains links to further resources about JMX.</para>
<itemizedlist>
<listitem>
<para>The <ulink url="http://java.sun.com/products/JavaManagement/">JMX homepage</ulink> at Sun</para>
<para>The <link xl:href="http://java.sun.com/products/JavaManagement/">JMX homepage</link> at Sun</para>
</listitem>
<listitem>
<para>The <ulink url="http://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html">JMX specification</ulink> (JSR-000003)</para>
<para>The <link xl:href="http://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html">JMX specification</link> (JSR-000003)</para>
</listitem>
<listitem>
<para>The <ulink url="http://jcp.org/aboutJava/communityprocess/final/jsr160/index.html">JMX Remote API specification</ulink> (JSR-000160)</para>
<para>The <link xl:href="http://jcp.org/aboutJava/communityprocess/final/jsr160/index.html">JMX Remote API specification</link> (JSR-000160)</para>
</listitem>
<listitem>
<para>The <ulink url="http://mx4j.sourceforge.net/">MX4J
homepage</ulink> (an Open Source implementation of various JMX
<para>The <link xl:href="http://mx4j.sourceforge.net/">MX4J
homepage</link> (an Open Source implementation of various JMX
specs)</para>
</listitem>
<listitem>
<para><ulink url="http://java.sun.com/developer/technicalArticles/J2SE/jmx.html">Getting Started with JMX</ulink> - an introductory article from Sun.</para>
<para><link xl:href="http://java.sun.com/developer/technicalArticles/J2SE/jmx.html">Getting Started with JMX</link> - an introductory article from Sun.</para>
</listitem>
</itemizedlist>
</section>

View File

@@ -1,66 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="mail"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="mail">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Email</title>
<section id="mail-introduction">
<section xml:id="mail-introduction">
<title>Introduction</title>
<sidebar>
<title>Library dependencies</title>
<para>The following additional jars to be on the classpath of your
application in order to be able to use the Spring Framework's email library.</para>
<itemizedlist>
<listitem>
<para>The <ulink url="http://java.sun.com/products/javamail/">JavaMail</ulink> <filename class="libraryfile">mail.jar</filename> library</para>
</listitem>
<listitem>
<para>The <ulink url="http://java.sun.com/products/javabeans/jaf/downloads/index.html">JAF</ulink> <filename class="libraryfile">activation.jar</filename> library</para>
</listitem>
</itemizedlist>
<para>All of these libraries are freely available on the web.</para>
</sidebar>
<sidebar>
<title>Library dependencies</title>
<para>The following additional jars to be on the classpath of your
application in order to be able to use the Spring Framework's email library.</para>
<itemizedlist>
<listitem>
<para>The <link xl:href="http://java.sun.com/products/javamail/">JavaMail</link> <filename class="libraryfile">mail.jar</filename> library</para>
</listitem>
<listitem>
<para>The <link xl:href="http://java.sun.com/products/javabeans/jaf/downloads/index.html">JAF</link> <filename class="libraryfile">activation.jar</filename> library</para>
</listitem>
</itemizedlist>
<para>All of these libraries are freely available on the web.</para>
</sidebar>
<para>The Spring Framework provides a helpful utility library for sending
email that shields the user from the specifics of the underlying mailing
system and is responsible for low level resource handling on behalf of
email that shields the user from the specifics of the underlying mailing
system and is responsible for low level resource handling on behalf of
the client.</para>
<para>The <literal>org.springframework.mail</literal> package is the root level package
for the Spring Framework's email support. The central interface for sending
emails is the <interfacename>MailSender</interfacename> interface; a simple value object
encapsulating the properties of a simple mail such as <emphasis>from</emphasis> and
<emphasis>to</emphasis> (plus many others) is the <classname>SimpleMailMessage</classname> class.
for the Spring Framework's email support. The central interface for sending
emails is the <interfacename>MailSender</interfacename> interface; a simple value object
encapsulating the properties of a simple mail such as <emphasis>from</emphasis> and
<emphasis>to</emphasis> (plus many others) is the <classname>SimpleMailMessage</classname> class.
This package also contains a hierarchy of checked exceptions which provide
a higher level of abstraction over the lower level mail system exceptions
with the root exception being <exceptionname>MailException</exceptionname>. Please
refer to the JavaDocs for more information on the rich mail exception hierarchy.</para>
<para>The <interfacename>org.springframework.mail.javamail.JavaMailSender</interfacename>
interface adds specialized <emphasis>JavaMail</emphasis> features such as MIME
interface adds specialized <emphasis>JavaMail</emphasis> features such as MIME
message support to the <interfacename>MailSender</interfacename> interface
(from which it inherits). <interfacename>JavaMailSender</interfacename> also provides a
callback interface for preparation of JavaMail MIME messages, called
(from which it inherits). <interfacename>JavaMailSender</interfacename> also provides a
callback interface for preparation of JavaMail MIME messages, called
<interfacename>org.springframework.mail.javamail.MimeMessagePreparator</interfacename></para>
</section>
<section id="mail-usage">
<title>Usage</title>
<para>Let's assume there is a business interface called <interfacename>OrderManager</interfacename>:</para>
<programlisting language="java"><![CDATA[public interface OrderManager {
<section xml:id="mail-usage">
<title>Usage</title>
<para>Let's assume there is a business interface called <interfacename>OrderManager</interfacename>:</para>
<programlisting language="java"><![CDATA[public interface OrderManager {
void placeOrder(Order order);
}]]></programlisting>
<para>Let us also assume that there is a requirement stating that an email message
with an order number needs to be generated and sent to a customer placing the
relevant order.</para>
<section id="mail-usage-simple">
<title>Basic <interfacename>MailSender</interfacename> and <classname>SimpleMailMessage</classname> usage</title>
<programlisting language="java"><![CDATA[import org.springframework.mail.MailException;
<para>Let us also assume that there is a requirement stating that an email message
with an order number needs to be generated and sent to a customer placing the
relevant order.</para>
<section xml:id="mail-usage-simple">
<title>Basic <interfacename>MailSender</interfacename> and <classname>SimpleMailMessage</classname> usage</title>
<programlisting language="java"><![CDATA[import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
@@ -96,13 +100,13 @@ public class SimpleOrderManager implements OrderManager {
}
catch(MailException ex) {
]]><lineannotation>// simply log it and go on...</lineannotation><![CDATA[
System.err.println(ex.getMessage());
System.err.println(ex.getMessage());
}
}
}]]></programlisting>
<para>Find below the bean definitions for the above code:</para>
<programlisting language="xml"><![CDATA[<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<para>Find below the bean definitions for the above code:</para>
<programlisting language="xml"><![CDATA[<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.mycompany.com"/>
</bean>
@@ -117,17 +121,17 @@ public class SimpleOrderManager implements OrderManager {
<property name="templateMessage" ref="templateMessage"/>
</bean>]]></programlisting>
</section>
<section id="mail-usage-mime">
<title>Using the <interfacename>JavaMailSender</interfacename> and the <classname>MimeMessagePreparator</classname></title>
<para>Here is another implementation of <interfacename>OrderManager</interfacename> using
the <interfacename>MimeMessagePreparator</interfacename> callback interface. Please note
in this case that the <literal>mailSender</literal> property is of type
<interfacename>JavaMailSender</interfacename> so that we are able to use the JavaMail
<classname>MimeMessage</classname> class:</para>
<programlisting language="java"><![CDATA[import javax.mail.Message;
</section>
<section xml:id="mail-usage-mime">
<title>Using the <interfacename>JavaMailSender</interfacename> and the <classname>MimeMessagePreparator</classname></title>
<para>Here is another implementation of <interfacename>OrderManager</interfacename> using
the <interfacename>MimeMessagePreparator</interfacename> callback interface. Please note
in this case that the <literal>mailSender</literal> property is of type
<interfacename>JavaMailSender</interfacename> so that we are able to use the JavaMail
<classname>MimeMessage</classname> class:</para>
<programlisting language="java"><![CDATA[import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
@@ -140,7 +144,7 @@ import org.springframework.mail.javamail.MimeMessagePreparator;
public class SimpleOrderManager implements OrderManager {
private JavaMailSender mailSender;
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
@@ -150,12 +154,12 @@ public class SimpleOrderManager implements OrderManager {
]]><lineannotation>// Do the business calculations...</lineannotation><![CDATA[
]]><lineannotation>// Call the collaborators to persist the order...</lineannotation><![CDATA[
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
mimeMessage.setRecipient(Message.RecipientType.TO,
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress(order.getCustomer().getEmailAddress()));
mimeMessage.setFrom(new InternetAddress("mail@mycompany.com"));
mimeMessage.setText(
@@ -170,33 +174,33 @@ public class SimpleOrderManager implements OrderManager {
}
catch (MailException ex) {
]]><lineannotation>// simply log it and go on...</lineannotation><![CDATA[
System.err.println(ex.getMessage());
System.err.println(ex.getMessage());
}
}
}]]></programlisting>
<note>
<para>The mail code is a crosscutting concern and could well be a candidate
for refactoring into a <link linkend="aop">custom Spring AOP aspect</link>,
which then could be executed at appropriate joinpoints on the
<interfacename>OrderManager</interfacename> target.</para>
</note>
<para>The Spring Framework's mail support ships with the standard JavaMail
implementation. Please refer to the relevant JavaDocs for more information.</para>
</section>
</section>
<section id="mail-javamail-mime">
<title>Using the JavaMail <classname>MimeMessageHelper</classname></title>
<para>A class that comes in pretty handy when dealing with JavaMail messages is
the <classname>org.springframework.mail.javamail.MimeMessageHelper</classname> class,
which shields you from having to use the verbose JavaMail API. Using
the <classname>MimeMessageHelper</classname> it is pretty easy to
create a <classname>MimeMessage</classname>:</para>
<programlisting language="java"><lineannotation>// of course you would use DI in any real-world cases</lineannotation><![CDATA[
<note>
<para>The mail code is a crosscutting concern and could well be a candidate
for refactoring into a <link linkend="aop">custom Spring AOP aspect</link>,
which then could be executed at appropriate joinpoints on the
<interfacename>OrderManager</interfacename> target.</para>
</note>
<para>The Spring Framework's mail support ships with the standard JavaMail
implementation. Please refer to the relevant JavaDocs for more information.</para>
</section>
</section>
<section xml:id="mail-javamail-mime">
<title>Using the JavaMail <classname>MimeMessageHelper</classname></title>
<para>A class that comes in pretty handy when dealing with JavaMail messages is
the <classname>org.springframework.mail.javamail.MimeMessageHelper</classname> class,
which shields you from having to use the verbose JavaMail API. Using
the <classname>MimeMessageHelper</classname> it is pretty easy to
create a <classname>MimeMessage</classname>:</para>
<programlisting language="java"><lineannotation>// of course you would use DI in any real-world cases</lineannotation><![CDATA[
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");
@@ -206,18 +210,18 @@ helper.setTo("test@host.com");
helper.setText("Thank you for ordering!");
sender.send(message);]]></programlisting>
<section id="mail-javamail-mime-attachments">
<title>Sending attachments and inline resources</title>
<para>Multipart email messages allow for both attachments and inline resources.
Examples of inline resources would be images or a stylesheet you want to use
in your message, but that you don't want displayed as an attachment.</para>
<section id="mail-javamail-mime-attachments-attachment">
<title>Attachments</title>
<para>The following example shows you how to use the
<classname>MimeMessageHelper</classname> to send an email along with a
single JPEG image attachment.</para>
<programlisting language="java"><![CDATA[JavaMailSenderImpl sender = new JavaMailSenderImpl();
<section xml:id="mail-javamail-mime-attachments">
<title>Sending attachments and inline resources</title>
<para>Multipart email messages allow for both attachments and inline resources.
Examples of inline resources would be images or a stylesheet you want to use
in your message, but that you don't want displayed as an attachment.</para>
<section xml:id="mail-javamail-mime-attachments-attachment">
<title>Attachments</title>
<para>The following example shows you how to use the
<classname>MimeMessageHelper</classname> to send an email along with a
single JPEG image attachment.</para>
<programlisting language="java"><![CDATA[JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");
MimeMessage message = sender.createMimeMessage();
@@ -233,13 +237,13 @@ FileSystemResource file = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addAttachment("CoolImage.jpg", file);
sender.send(message);]]></programlisting>
</section>
<section id="mail-javamail-mime-attachments-inline">
<title>Inline resources</title>
<para>The following example shows you how to use the
<classname>MimeMessageHelper</classname> to send an email along with an
inline image.</para>
<programlisting language="java"><![CDATA[JavaMailSenderImpl sender = new JavaMailSenderImpl();
</section>
<section xml:id="mail-javamail-mime-attachments-inline">
<title>Inline resources</title>
<para>The following example shows you how to use the
<classname>MimeMessageHelper</classname> to send an email along with an
inline image.</para>
<programlisting language="java"><![CDATA[JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");
MimeMessage message = sender.createMimeMessage();
@@ -256,57 +260,57 @@ FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addInline("identifier1234", res);
sender.send(message);]]></programlisting>
<warning>
<para>Inline resources are added to the mime message using the
specified <literal>Content-ID</literal> (<literal>identifier1234</literal>
in the above example). The order in which you are adding the text and the
resource are <emphasis role="bold">very</emphasis> important. Be sure to
<emphasis>first add the text</emphasis> and after that the resources. If
you are doing it the other way around, it won't work!</para>
</warning>
</section>
</section>
<section id="mail-templates">
<title>Creating email content using a templating library</title>
<para>The code in the previous examples explicitly created the
content of the email message, using methods calls such as
<methodname>message.setText(..)</methodname>. This is fine for
simple cases, and it is okay in the context of the aforementioned
examples, where the intent was to show you the very basics of the API.</para>
<para>In your typical enterprise application though, you are not going
to create the content of your emails using the above approach for a number
of reasons.</para>
<para>
<itemizedlist>
<listitem>
<para>Creating HTML-based email content in Java code is tedious and error prone</para>
</listitem>
<listitem>
<para>There is no clear separation between display logic and business logic</para>
</listitem>
<listitem>
<para>Changing the display structure of the email content requires writing Java code, recompiling, redeploying...</para>
</listitem>
</itemizedlist>
</para>
<para>Typically the approach taken to address these issues is to use a template library
such as FreeMarker or Velocity to define the display structure of email content. This leaves
your code tasked only with creating the data that is to be rendered in the email
template and sending the email. It is definitely a best practice for when
the content of your emails becomes even moderately complex, and with
the Spring Framework's support classes for FreeMarker and Velocity becomes
quite easy to do. Find below an example of using the Velocity template library
to create email content.</para>
<section id="mail-templates-example">
<title>A Velocity-based example</title>
<para>To use <ulink url="http://velocity.apache.org">Velocity</ulink> to
create your email template(s), you will need to have the Velocity libraries
available on your classpath. You will also need to create one or more Velocity templates
for the email content that your application needs. Find below the Velocity
template that this example will be using. As you can see it is HTML-based,
and since it is plain text it can be created using your favorite HTML
or text editor.</para>
<programlisting language="xml"><lineannotation># in the <literal>com/foo/package</literal></lineannotation><![CDATA[
<warning>
<para>Inline resources are added to the mime message using the
specified <literal>Content-ID</literal> (<literal>identifier1234</literal>
in the above example). The order in which you are adding the text and the
resource are <emphasis role="bold">very</emphasis> important. Be sure to
<emphasis>first add the text</emphasis> and after that the resources. If
you are doing it the other way around, it won't work!</para>
</warning>
</section>
</section>
<section xml:id="mail-templates">
<title>Creating email content using a templating library</title>
<para>The code in the previous examples explicitly created the
content of the email message, using methods calls such as
<methodname>message.setText(..)</methodname>. This is fine for
simple cases, and it is okay in the context of the aforementioned
examples, where the intent was to show you the very basics of the API.</para>
<para>In your typical enterprise application though, you are not going
to create the content of your emails using the above approach for a number
of reasons.</para>
<para>
<itemizedlist>
<listitem>
<para>Creating HTML-based email content in Java code is tedious and error prone</para>
</listitem>
<listitem>
<para>There is no clear separation between display logic and business logic</para>
</listitem>
<listitem>
<para>Changing the display structure of the email content requires writing Java code, recompiling, redeploying...</para>
</listitem>
</itemizedlist>
</para>
<para>Typically the approach taken to address these issues is to use a template library
such as FreeMarker or Velocity to define the display structure of email content. This leaves
your code tasked only with creating the data that is to be rendered in the email
template and sending the email. It is definitely a best practice for when
the content of your emails becomes even moderately complex, and with
the Spring Framework's support classes for FreeMarker and Velocity becomes
quite easy to do. Find below an example of using the Velocity template library
to create email content.</para>
<section xml:id="mail-templates-example">
<title>A Velocity-based example</title>
<para>To use <link xl:href="http://velocity.apache.org">Velocity</link> to
create your email template(s), you will need to have the Velocity libraries
available on your classpath. You will also need to create one or more Velocity templates
for the email content that your application needs. Find below the Velocity
template that this example will be using. As you can see it is HTML-based,
and since it is plain text it can be created using your favorite HTML
or text editor.</para>
<programlisting language="xml"><lineannotation># in the com/foo/package</lineannotation><![CDATA[
<html>
<body>
<h3>Hi ${user.userName}, welcome to the Chipping Sodbury On-the-Hill message boards!</h3>
@@ -317,10 +321,10 @@ sender.send(message);]]></programlisting>
</body>
</html>]]></programlisting>
<para>Find below some simple code and Spring XML configuration that
makes use of the above Velocity template to create email content and
send email(s).</para>
<programlisting language="java"><![CDATA[package com.foo;
<para>Find below some simple code and Spring XML configuration that
makes use of the above Velocity template to create email content and
send email(s).</para>
<programlisting language="java"><![CDATA[package com.foo;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.javamail.JavaMailSender;
@@ -368,7 +372,7 @@ public class SimpleRegistrationService implements RegistrationService {
this.mailSender.send(preparator);
}
}]]></programlisting>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
@@ -382,7 +386,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans
<property name="mailSender" ref="mailSender"/>
<property name="velocityEngine" ref="velocityEngine"/>
</bean>
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<value>
@@ -393,8 +397,8 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans
</bean>
</beans>]]></programlisting>
</section>
</section>
</section>
</section>
</section>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="new-in-3.0"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="new-in-3.0">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>New Features and Enhancements in Spring 3.0</title>
<para>If you have been using the Spring Framework for some time, you will be
@@ -10,7 +14,7 @@
October 2006, and Spring 2.5, released in November 2007. It is now time for
a third overhaul resulting in Spring 3.0.</para>
<sidebar id="new-in-3.0-intro-java">
<sidebar xml:id="new-in-3.0-intro-java">
<title>Java SE and Java EE Support</title>
<para>The Spring Framework is now based on Java 5, and Java 6 is fully
@@ -20,7 +24,7 @@
at the same time introducing some early support for Java EE 6.</para>
</sidebar>
<section id="new-in-3.0-intro">
<section xml:id="new-in-3.0-intro">
<title>Java 5</title>
<para>The entire framework code has been revised to take advantage of Java
@@ -44,7 +48,7 @@
@Asynchronous annotation).</para>
</section>
<section id="new-in-3.0-improved-docs">
<section xml:id="new-in-3.0-improved-docs">
<title>Improved documentation</title>
<para>The Spring reference documentation has also substantially been
@@ -53,36 +57,36 @@
this documentation, some errors may nevertheless have crept in. If you do
spot any typos or even more serious errors, and you can spare a few cycles
during lunch, please do bring the error to the attention of the Spring
team by <ulink url="http://jira.springframework.org/">raising an
issue</ulink>.</para>
team by <link xl:href="http://jira.springframework.org/">raising an
issue</link>.</para>
</section>
<section id="new-in-3.0-new-tutorial">
<section xml:id="new-in-3.0-new-tutorial">
<title>New articles and tutorials</title>
<para>
There are many excellent articles and tutorials that show how to get started with Spring 3 features.
Read them at the <ulink url="http://www.springsource.org/documentation">Spring Documentation</ulink> page.
</para>
<para id="new-in-3.0-samples">
The samples have been improved and updated to take advantage of the new features in Spring 3.
Additionally, the samples have been moved out of the source tree into a dedicated SVN
<ulink url="https://anonsvn.springframework.org/svn/spring-samples/">repository</ulink> available at:</para>
There are many excellent articles and tutorials that show how to get started with Spring 3 features.
Read them at the <link xl:href="http://www.springsource.org/documentation">Spring Documentation</link> page.
</para>
<para xml:id="new-in-3.0-samples">
The samples have been improved and updated to take advantage of the new features in Spring 3.
Additionally, the samples have been moved out of the source tree into a dedicated SVN
<link xl:href="https://anonsvn.springframework.org/svn/spring-samples/">repository</link> available at:</para>
<para>
<literal>https://anonsvn.springframework.org/svn/spring-samples/</literal>
</para>
<para>As such, the samples are no longer distributed alongside Spring 3 and need to be downloaded separately from the repository mentioned above. However, this documentation
will continue to refer to some samples (in particular Petclinic) to illustrate various features.</para>
<note>For more information on Subversion (or in short SVN), see the project homepage at:
<literal>http://subversion.apache.org/</literal>
</note>
<literal>https://anonsvn.springframework.org/svn/spring-samples/</literal>
</para>
<para>As such, the samples are no longer distributed alongside Spring 3 and need to be downloaded separately from the repository mentioned above. However, this documentation
will continue to refer to some samples (in particular Petclinic) to illustrate various features.</para>
<note><para>For more information on Subversion (or in short SVN), see the project homepage at:
<literal>http://subversion.apache.org/</literal></para>
</note>
</section>
<section id="new-in-3.0-modules-build">
<section xml:id="new-in-3.0-modules-build">
<title>New module organization and build system</title>
<para>The framework modules have been revised and are now managed
@@ -154,7 +158,7 @@
</listitem>
</itemizedlist>
<sidebar id="new-in-3.0-intro-spring-jar">
<sidebar xml:id="new-in-3.0-intro-spring-jar">
<title>Note:</title>
<para>The spring.jar artifact that contained almost the entire framework
@@ -183,7 +187,7 @@
</itemizedlist>
</section>
<section id="new-in-3.0-features-overview">
<section xml:id="new-in-3.0-features-overview">
<title>Overview of new features</title>
<para>This is a list of new features for Spring 3.0. We will cover these
@@ -229,7 +233,7 @@
</listitem>
</itemizedlist>
<section id="new-feature-java5">
<section xml:id="new-feature-java5">
<title>Core APIs updated for Java 5</title>
<para>BeanFactory interface returns typed bean instances as far as
@@ -269,7 +273,7 @@
<para>Typed ApplicationListener&lt;E&gt;</para>
</section>
<section id="new-feature-el">
<section xml:id="new-feature-el">
<title>Spring Expression Language</title>
<para>Spring introduces an expression language which is similar to
@@ -285,8 +289,8 @@
across all the products in the Spring portfolio. Its language features
are driven by the requirements of the projects in the Spring portfolio,
including tooling requirements for code completion support within the
Eclipse based <ulink url="http://www.springsource.com/products/sts">SpringSource
Tool Suite</ulink>.</para>
Eclipse based <link xl:href="http://www.springsource.com/products/sts">SpringSource
Tool Suite</link>.</para>
<para>The following is an example of how the Expression Language can be
used to configure some properties of a database setup <programlisting
@@ -299,7 +303,7 @@
</programlisting></para>
<para>This functionality is also available if you prefer to configure
your components using annotations: <programlisting language="java">@Repository
your components using annotations: <programlisting language="java">@Repository
public class RewardsTestDatabase {
@Value("#{systemProperties.databaseName}")
@@ -311,14 +315,14 @@ public class RewardsTestDatabase {
</programlisting></para>
</section>
<section id="new-feature-java-config">
<section xml:id="new-feature-java-config">
<title>The Inversion of Control (IoC) container</title>
<section id="new-java-configuration">
<section xml:id="new-java-configuration">
<title>Java based bean metadata</title>
<para>Some core features from the <ulink
url="http://www.springsource.org/javaconfig">JavaConfig</ulink>
<para>Some core features from the <link
xl:href="http://www.springsource.org/javaconfig">JavaConfig</link>
project have been added to the Spring Framework now. This means that
the following annotations are now directly supported: <itemizedlist>
<listitem>
@@ -376,7 +380,7 @@ public class AppConfig {
@Bean
public SessionFactory sessionFactory() {
// wire up a session factory
AnnotationSessionFactoryBean asFactoryBean =
AnnotationSessionFactoryBean asFactoryBean =
new AnnotationSessionFactoryBean();
asFactoryBean.setDataSource(dataSource());
// additional config
@@ -384,7 +388,7 @@ public class AppConfig {
}
@Bean
public DataSource dataSource() {
public DataSource dataSource() {
return new DriverManagerDataSource(jdbcUrl, username, password);
}
}
@@ -404,7 +408,7 @@ public class AppConfig {
<literal>AnnotationConfigApplicationContext</literal>.</para>
</section>
<section id="new-bean-metadata-in-components">
<section xml:id="new-bean-metadata-in-components">
<title>Defining bean metadata within components</title>
<para><literal>@Bean</literal> annotated methods are also supported
@@ -415,7 +419,7 @@ public class AppConfig {
</section>
</section>
<section id="new-feature-convert-and-format">
<section xml:id="new-feature-convert-and-format">
<title>General purpose type conversion system and field formatting
system</title>
@@ -430,7 +434,7 @@ public class AppConfig {
environments such as Spring MVC.</para>
</section>
<section id="new-feature-oxm">
<section xml:id="new-feature-oxm">
<title>The Data Tier</title>
<para>Object to XML mapping functionality (OXM) from the Spring Web
@@ -441,14 +445,14 @@ public class AppConfig {
Mappers</link> chapter.</para>
</section>
<section id="new-feature-rest">
<section xml:id="new-feature-rest">
<title>The Web Tier</title>
<para>The most exciting new feature for the Web Tier is the support for
building RESTful web services and web applications. There are also some
new annotations that can be used in any web application.</para>
<section id="new-feature-rest-support">
<section xml:id="new-feature-rest-support">
<title>Comprehensive REST support</title>
<para>Server-side support for building RESTful applications has been
@@ -471,7 +475,7 @@ public class AppConfig {
information.</para>
</section>
<section id="new-feature-at-mvc">
<section xml:id="new-feature-at-mvc">
<title>@MVC additions</title>
<para>A <literal>mvc</literal> namespace has been introduced that greatly simplifies Spring MVC configuration.</para>
@@ -486,14 +490,14 @@ public class AppConfig {
</section>
</section>
<section id="new-feature-validation">
<section xml:id="new-feature-validation">
<title>Declarative model validation</title>
<para>Several <link linkend="validation-beanvalidation">validation enhancements</link>,
including JSR 303 support that uses Hibernate Validator as the default provider.</para>
</section>
<section id="new-feature-jee-6">
<section xml:id="new-feature-jee-6">
<title>Early support for Java EE 6</title>
<para>We provide support for asynchronous method invocations through the
@@ -504,7 +508,7 @@ public class AppConfig {
</section>
<section id="new-feature-embedded-databases">
<section xml:id="new-feature-embedded-databases">
<title>Support for embedded databases</title>
<para>Convenient support for <link

View File

@@ -1,22 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="new-in-3.1"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="new-in-3.1">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>New Features and Enhancements in Spring 3.1</title>
<para>Building on the support introduced in Spring 3.0, Spring 3.1 is
currently under development, and at the time of this writing Spring 3.1 RC1
is being prepared for release.</para>
<section id="new-in-3.1-features-overview">
<section xml:id="new-in-3.1-features-overview">
<title>Overview of new features</title>
<para>This is a list of new features for Spring 3.1. Most features do not
yet have dedicated reference documentation but do have Javadoc. In such
cases, fully-qualified class names are given.</para>
<section id="new-in-3.1-cache-abstraction">
<section xml:id="new-in-3.1-cache-abstraction">
<title>Cache Abstraction</title>
<itemizedlist>
@@ -25,27 +29,27 @@
</listitem>
<listitem>
<para><ulink
url="http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/">
Cache Abstraction</ulink> (SpringSource team blog)</para>
<para><link
xl:href="http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/">
Cache Abstraction</link> (SpringSource team blog)</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-3.1-bean-definition-profiles">
<section xml:id="new-in-3.1-bean-definition-profiles">
<title>Bean Definition Profiles</title>
<itemizedlist>
<listitem>
<para><ulink
url="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/">
XML profiles</ulink> (SpringSource Team Blog)</para>
<para><link
xl:href="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/">
XML profiles</link> (SpringSource Team Blog)</para>
</listitem>
<listitem>
<para><ulink
url="http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/">
Introducing @Profile</ulink> (SpringSource Team Blog)</para>
<para><link
xl:href="http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/">
Introducing @Profile</link> (SpringSource Team Blog)</para>
</listitem>
<listitem>
@@ -60,14 +64,14 @@
</itemizedlist>
</section>
<section id="new-in-3.1-environment-abstraction">
<section xml:id="new-in-3.1-environment-abstraction">
<title>Environment Abstraction</title>
<itemizedlist>
<listitem>
<para><ulink
url="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/">
Environment Abstraction</ulink> (SpringSource Team Blog)</para>
<para><link
xl:href="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/">
Environment Abstraction</link> (SpringSource Team Blog)</para>
</listitem>
<listitem>
@@ -76,14 +80,14 @@
</itemizedlist>
</section>
<section id="new-in-3.1-property-source-abstraction">
<section xml:id="new-in-3.1-property-source-abstraction">
<title>PropertySource Abstraction</title>
<itemizedlist>
<listitem>
<para><ulink
url="http://blog.springsource.com/2011/02/15/spring-3-1-m1-unified-property-management/">
Unified Property Management</ulink> (SpringSource Team Blog)</para>
<para><link
xl:href="http://blog.springsource.com/2011/02/15/spring-3-1-m1-unified-property-management/">
Unified Property Management</link> (SpringSource Team Blog)</para>
</listitem>
<listitem>
@@ -101,7 +105,7 @@
</itemizedlist>
</section>
<section id="new-in-3.1-code-equivalent-xml-namespaces">
<section xml:id="new-in-3.1-code-equivalent-xml-namespaces">
<title>Code equivalents for Spring's XML namespaces</title>
<para>Code-based equivalents to popular Spring XML namespace elements
@@ -169,7 +173,7 @@
</itemizedlist>
</section>
<section id="new-in-3.1-hibernate-4-support">
<section xml:id="new-in-3.1-hibernate-4-support">
<title>Support for Hibernate 4.x</title>
<itemizedlist>
@@ -180,7 +184,7 @@
</itemizedlist>
</section>
<section id="new-in-3.1-test-context-profiles">
<section xml:id="new-in-3.1-test-context-profiles">
<title>TestContext framework support for @Configuration classes and bean
definition profiles</title>
@@ -195,9 +199,9 @@
<itemizedlist>
<listitem>
<para><ulink
url="http://blog.springsource.com/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/">Spring
3.1 M2: Testing with @Configuration Classes and Profiles</ulink>
<para><link
xl:href="http://blog.springsource.com/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/">Spring
3.1 M2: Testing with @Configuration Classes and Profiles</link>
(SpringSource Team Blog)</para>
</listitem>
@@ -238,7 +242,7 @@
</itemizedlist>
</section>
<section id="new-in-3.1-c-namespace">
<section xml:id="new-in-3.1-c-namespace">
<title>c: namespace for more concise constructor injection</title>
<itemizedlist>
@@ -248,7 +252,7 @@
</itemizedlist>
</section>
<section id="new-in-3.1-injection-non-javabeans-setters">
<section xml:id="new-in-3.1-injection-non-javabeans-setters">
<title>Support for injection against non-standard JavaBeans
setters</title>
@@ -260,7 +264,7 @@
setter methods return a reference to 'this'.</para>
</section>
<section id="new-in-3.1-servlet-3-code-config">
<section xml:id="new-in-3.1-servlet-3-code-config">
<title>Support for Servlet 3 code-based configuration of Servlet
Container</title>
@@ -276,15 +280,15 @@
</listitem>
<listitem>
<para><ulink url="http://bit.ly/lrDHja">Diff from Spring's
Greenhouse reference application</ulink> demonstrating migration
<para><link xl:href="http://bit.ly/lrDHja">Diff from Spring's
Greenhouse reference application</link> demonstrating migration
from web.xml to
<interfacename>WebApplicationInitializer</interfacename></para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-3.1-servlet-3-multipart-resolver">
<section xml:id="new-in-3.1-servlet-3-multipart-resolver">
<title>Support for Servlet 3 MultipartResolver</title>
<itemizedlist>
@@ -296,7 +300,7 @@
</itemizedlist>
</section>
<section id="new-in-3.1-jpa-without-xml">
<section xml:id="new-in-3.1-jpa-without-xml">
<title>JPA EntityManagerFactory bootstrapping without
persistence.xml</title>
@@ -320,7 +324,7 @@
initializer.</para>
</section>
<section id="new-in-3.1-handler-method-controller-processing">
<section xml:id="new-in-3.1-handler-method-controller-processing">
<title>New HandlerMethod-based Support Classes For Annotated Controller
Processing</title>
@@ -380,7 +384,7 @@
<para>A second notable difference is the introduction of a
<classname>HandlerMethod</classname> abstraction to represent an
<interface>@RequestMapping</interface> method. This abstraction is used
<interfacename>@RequestMapping</interfacename> method. This abstraction is used
throughout by the new support classes as the <literal>handler</literal>
instance. For example a <classname>HandlerInterceptor</classname> can
cast the <literal>handler</literal> from <classname>Object</classname>
@@ -388,7 +392,7 @@
controller method, its annotations, etc.</para>
<para>The new classes are enabled by default by the MVC namespace and by
Java-based configuration via <interface>@EnableWebMvc</interface>. The
Java-based configuration via <interfacename>@EnableWebMvc</interfacename>. The
existing classes will continue to be available but use of the new
classes is recommended going forward.</para>
@@ -397,9 +401,9 @@
</section>
<section id="new-in-3.1-request-mapping-consumes-produces">
<section xml:id="new-in-3.1-request-mapping-consumes-produces">
<title>"consumes" and "produces" conditions in
<interface>@RequestMapping</interface></title>
<interfacename>@RequestMapping</interfacename></title>
<para>Improved support for specifying media types consumed by a method
through the <literal>'Content-Type'</literal> header as well as for
@@ -408,7 +412,7 @@
linkend="mvc-ann-requestmapping-produces" /></para>
</section>
<section id="new-in-3.1-flash-redirect-attributes">
<section xml:id="new-in-3.1-flash-redirect-attributes">
<title>Flash Attributes and
<interfacename>RedirectAttributes</interfacename></title>
@@ -426,7 +430,7 @@
for more details.</para>
</section>
<section id="new-in-3.1-uri-template-var-enhancements">
<section xml:id="new-in-3.1-uri-template-var-enhancements">
<title>URI Template Variable Enhancements</title>
<para>URI template variables from the current request are used in more
@@ -461,20 +465,20 @@
</itemizedlist></para>
</section>
<section id="new-in-3.1-mvc-valid-requestbody">
<section xml:id="new-in-3.1-mvc-valid-requestbody">
<title><interfacename>@Valid</interfacename> On
<interface>@RequestBody</interface> Controller Method Arguments</title>
<interfacename>@RequestBody</interfacename> Controller Method Arguments</title>
<para>An <interface>@RequestBody</interface> method argument can be
annotated with <interface>@Valid</interface> to invoke automatic
<para>An <interfacename>@RequestBody</interfacename> method argument can be
annotated with <interfacename>@Valid</interfacename> to invoke automatic
validation similar to the support for
<interface>@ModelAttribute</interface> method arguments. A resulting
<interfacename>@ModelAttribute</interfacename> method arguments. A resulting
<classname>MethodArgumentNotValidException</classname> is handled in the
<classname>DefaultHandlerExceptionResolver</classname> and results in a
<literal>400</literal> response code.</para>
</section>
<section id="new-in-3.1-mvc-requestpart">
<section xml:id="new-in-3.1-mvc-requestpart">
<title><interfacename>@RequestPart</interfacename> Annotation On
Controller Method Arguments</title>
@@ -484,7 +488,7 @@
linkend="mvc-multipart" />.</para>
</section>
<section id="new-in-3.1-mvc-uricomponentsbuilder">
<section xml:id="new-in-3.1-mvc-uricomponentsbuilder">
<title><classname>UriComponentsBuilder</classname> and <classname>UriComponents</classname></title>
<para>A new <classname>UriComponents</classname> class has been added,

View File

@@ -1,19 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="new-in-3.2"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="new-in-3.2">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>New Features and Enhancements in Spring 3.2</title>
<section id="new-in-3.2-features-overview">
<section xml:id="new-in-3.2-features-overview">
<title>Overview of new features</title>
<section id="new-in-3.2-webmvc-async">
<section xml:id="new-in-3.2-webmvc-async">
<title>Support for Servlet 3 based asynchronous request processing</title>
<para>The Spring MVC programming model now provides explicit Servlet 3 async support.
<interfacename>@RequestMapping</interfacename> methods can return one of:</para>
<itemizedlist>
<listitem>
<para><interfacename>java.util.concurrent.Callable</interfacename> to
@@ -31,14 +35,14 @@
customize the timeout value or the task executor to use.</para>
</listitem>
</itemizedlist>
<para>See <ulink
url="http://blog.springsource.org/2012/05/06/spring-mvc-3-2-preview-introducing-servlet-3-async-support/">
Introducing Servlet 3 Async Support</ulink> (SpringSource team blog).</para>
<para>See <link
xl:href="http://blog.springsource.org/2012/05/06/spring-mvc-3-2-preview-introducing-servlet-3-async-support/">
Introducing Servlet 3 Async Support</link> (SpringSource team blog).</para>
</section>
<section id="new-in-3.2-spring-mvc-test">
<section xml:id="new-in-3.2-spring-mvc-test">
<title>Spring MVC Test framework</title>
<para>First-class support for testing Spring MVC applications with a
@@ -47,13 +51,13 @@
REST tests rely on the <classname>RestTemplate</classname>.
See the following presentation for more information before
documentation is added:
<ulink url="https://github.com/rstoyanchev/spring-32-test-webapps">
"Testing Web Applications with Spring 3.2"</ulink>.
<link xl:href="https://github.com/rstoyanchev/spring-32-test-webapps">
"Testing Web Applications with Spring 3.2"</link>.
</para>
</section>
<section id="new-in-3.2-webmvc-content-negotiation">
<section xml:id="new-in-3.2-webmvc-content-negotiation">
<title>Content negotiation improvements</title>
<para>A <interfacename>ContentNeogtiationStrategy</interfacename> is now
@@ -75,14 +79,14 @@
<para>The introduction of <classname>ContentNegotiationManger</classname>
also enables smart suffix pattern matching for incoming requests.
See <ulink url="https://github.com/SpringSource/spring-framework/commit/4fd7645">
commit message</ulink></para>
See <link xl:href="https://github.com/SpringSource/spring-framework/commit/4fd7645">
commit message</link></para>
</section>
<section id="new-in-3.2-webmvc-controller-advice">
<section xml:id="new-in-3.2-webmvc-controller-advice">
<title><interfacename>@ControllerAdvice</interfacename> annotation</title>
<para>Classes annotated with <interfacename>@ControllerAdvice</interfacename>
can contain <interfacename>@ExceptionHandler</interfacename>,
<interfacename>@InitBinder</interfacename>, and
@@ -92,10 +96,10 @@
<interfacename>@ControllerAdvice</interfacename> is
a component annotation allowing implementation classes to be auto-detected
through classpath scanning.</para>
</section>
<section id="new-in-3.2-matrix-variables">
<section xml:id="new-in-3.2-matrix-variables">
<title>Matrix variables</title>
<para>A new <interfacename>@MatrixVariable</interfacename> annotation
@@ -103,7 +107,7 @@
For more details see <xref linkend="mvc-ann-matrix-variables"/>.</para>
</section>
<section id="new-in-3.2-dispatcher-servlet-initializer">
<section xml:id="new-in-3.2-dispatcher-servlet-initializer">
<title>Abstract base class for code-based Servlet 3+ container initialization</title>
<para>An abstract base class implementation of the
@@ -116,7 +120,7 @@
For more details see <xref linkend="mvc-container-config"/>.</para>
</section>
<section id="new-in-3.2-webmvc-exception-handler-support">
<section xml:id="new-in-3.2-webmvc-exception-handler-support">
<title><classname>ResponseEntityExceptionHandler</classname> class</title>
<para>A convenient base class with an
@@ -132,7 +136,7 @@
</section>
<section id="new-in-3.2-webmvc-generic-types-rest-template">
<section xml:id="new-in-3.2-webmvc-generic-types-rest-template">
<title>Support for generic types in the <classname>RestTemplate</classname> and in
<interfacename>@RequestBody</interfacename> arguments</title>
@@ -152,10 +156,10 @@
generic type is a JAXB type annotated with
<interfacename>@XmlRootElement</interfacename> or
<interfacename>@XmlType</interfacename>.</para>
</section>
<section id="new-in-3.2-webmvc-jackson-json">
<section xml:id="new-in-3.2-webmvc-jackson-json">
<title>Jackson JSON 2 and related improvements</title>
<para>The Jackson Json 2 library is now supported. Due to packaging changes in
@@ -170,7 +174,7 @@
</section>
<section id="new-in-3.2-webmvc-request-body-arg-with-binding-result">
<section xml:id="new-in-3.2-webmvc-request-body-arg-with-binding-result">
<title><interfacename>@RequestBody</interfacename> improvements</title>
<para>An <interfacename>@RequestBody</interfacename> or an
@@ -183,7 +187,7 @@
</section>
<section id="new-in-3.2-webmvc-http-patch">
<section xml:id="new-in-3.2-webmvc-http-patch">
<title>HTTP PATCH method</title>
<para>The HTTP request method <code>PATCH</code> may now be used in
@@ -195,7 +199,7 @@
</section>
<section id="new-in-3.2-webmvc-mapped-interceptor-exclude-patterns">
<section xml:id="new-in-3.2-webmvc-mapped-interceptor-exclude-patterns">
<title>Excluded patterns in mapped interceptors</title>
<para>Mapped interceptors now support URL patterns to be excluded.

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="orm"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="orm">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Object Relational Mapping (ORM) Data Access</title>
<section id="orm-introduction">
<section xml:id="orm-introduction">
<title>Introduction to ORM with Spring</title>
<para>The Spring Framework supports integration
@@ -42,7 +46,7 @@
it easy to swap the implementations and configuration locations of
Hibernate <interfacename>SessionFactory</interfacename> instances,
JDBC <interfacename>DataSource</interfacename> instances, transaction
managers, and mapped object implementations (if needed). <!--I changed *mappes* to *mapped*; is that what you mean? Also, clarify whether *if needed* refers only to that or to the rest as well
managers, and mapped object implementations (if needed). <!--I changed *mappes* to *mapped*; is that what you mean? Also, clarify whether *if needed* refers only to that or to the rest as well
TR: OK. Refers only to mapped object implementations-->This in turn makes it
much easier to test each piece of persistence-related code in
isolation.<!--deleted redundancy; sentence already refers to isolating each piece of code. TR: OK. moved isolation to the end--></para>
@@ -75,7 +79,7 @@ TR: OK. Refers only to mapped object implementations-->This in turn makes it
<interfacename>Session</interfacename> to ensure efficiency and proper
transaction handling. Spring makes it easy to create and bind a
<interfacename>Session</interfacename> to the current thread
transparently, <!--This bullet and next refer to template wrapper class. Is this referring to using Spring DAO templates, whichis no longer recommend--><!--ed? If so, it's confusing to discuss it as an option. Sends a mixed message. If not, explain what you mean by *template* wrapper class.
transparently, <!--This bullet and next refer to template wrapper class. Is this referring to using Spring DAO templates, whichis no longer recommend--><!--ed? If so, it's confusing to discuss it as an option. Sends a mixed message. If not, explain what you mean by *template* wrapper class.
TR: REVISED, PLS REVIEW. Good point, removed coverage of template wrapper.-->by
exposing a current <interfacename>Session</interfacename> through the
Hibernate <interfacename>SessionFactory</interfacename>. Thus Spring
@@ -105,15 +109,15 @@ TR: REVISED, PLS REVIEW. Good point, removed coverage of template wrapper.-->by
</listitem>
</itemizedlist>
<para><!--The PetClinic sample in the Spring distribution offers alternative DAO implementations and application context configurations for JDBC,
Hibernate, and JPA. PetClinic is a working sample application that illustrates the use of Hibernate and JPA in a Spring web application.
<para><!--The PetClinic sample in the Spring distribution offers alternative DAO implementations and application context configurations for JDBC,
Hibernate, and JPA. PetClinic is a working sample application that illustrates the use of Hibernate and JPA in a Spring web application.
It also leverages declarative transaction demarcation with different transaction strategies.
Beyond the samples shipped with Spring, vendors provide a variety of Spring-based ORM samples. --><!--Name vendors, link to them? TR: WILL ADDRESS LATER. We need to point to the current samples which aren't completed yet. --><emphasis>TODO:
provide links to current samples</emphasis></para>
</section>
<section id="orm-general">
<section xml:id="orm-general">
<title>General ORM integration considerations</title>
<para>This section highlights considerations that apply to all ORM
@@ -137,14 +141,14 @@ Beyond the samples shipped with Spring, vendors provide a variety of Spring-base
objects and transaction managers, web view resolvers, web controllers that
use the business services,and so on.</para>
<section id="orm-resource-mngmnt">
<section xml:id="orm-resource-mngmnt">
<title>Resource and transaction management</title>
<para>Typical business applications are cluttered with repetitive
resource management code. Many projects try to invent their own
solutions, sometimes sacrificing proper handling of failures for
programming convenience. Spring advocates simple solutions for proper
resource handling, namely IoC through templating<!--same question as before re templates. Does preceding refer to Spring templates that in beginning you say you no longer recommend?
resource handling, namely IoC through templating<!--same question as before re templates. Does preceding refer to Spring templates that in beginning you say you no longer recommend?
TR: OK AS IS. The template for JDBC is still recommended--> in the case of
JDBC and applying AOP interceptors for the ORM technologies.</para>
@@ -170,7 +174,7 @@ TR: OK AS IS. The template for JDBC is still recommended--> in the case of
chapter.</para>
</section>
<section id="orm-exception-translation">
<section xml:id="orm-exception-translation">
<title>Exception translation</title>
<para>When you use Hibernate, JPA, or JDO in a DAO, you must decide how
@@ -200,7 +204,7 @@ public class ProductDaoImpl implements ProductDao {
<programlisting language="xml">&lt;beans&gt;
<lineannotation>&lt;!-- <classname>Exception</classname> translation bean post processor --&gt;</lineannotation>
<lineannotation>&lt;!-- Exception translation bean post processor --&gt;</lineannotation>
&lt;bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/&gt;
&lt;bean id="myProductDao" class="product.ProductDaoImpl"/&gt;
@@ -223,11 +227,11 @@ public class ProductDaoImpl implements ProductDao {
</section>
</section>
<section id="orm-hibernate">
<section xml:id="orm-hibernate">
<title>Hibernate</title>
<para>We will start with a coverage of <ulink
url="http://www.hibernate.org/">Hibernate 3</ulink> in a Spring
<para>We will start with a coverage of <link
xl:href="http://www.hibernate.org/">Hibernate 3</link> in a Spring
environment, using it to demonstrate the approach that Spring takes
towards integrating O/R mappers. This section will cover many issues in
detail and show different variations of DAO implementations and
@@ -238,7 +242,7 @@ public class ProductDaoImpl implements ProductDao {
<para><note><para>As of Spring 3.0, Spring requires Hibernate 3.2 or later.</para></note></para>
<section id="orm-session-factory-setup">
<section xml:id="orm-session-factory-setup">
<title><interfacename>SessionFactory</interfacename> setup in a Spring
container</title>
@@ -298,7 +302,7 @@ public class ProductDaoImpl implements ProductDao {
However, that is typically not common outside of an EJB context.</para>
</section>
<section id="orm-hibernate-straight">
<section xml:id="orm-hibernate-straight">
<title>Implementing DAOs based on plain Hibernate 3 API</title>
<para>Hibernate 3 has a feature called contextual sessions, wherein
@@ -382,14 +386,14 @@ public class ProductDaoImpl implements ProductDao {
transactions.</para>
</section>
<section id="orm-hibernate-tx-declarative">
<section xml:id="orm-hibernate-tx-declarative">
<title>Declarative transaction demarcation</title>
<para>We recommend that you use Spring's declarative transaction
support, which enables you to replace explicit transaction demarcation
API calls in your Java code with an AOP transaction interceptor. This
transaction interceptor can be configured in a Spring container using
either Java annotations or XML.<!--Reword last part of preceding sentence to clarify *what* is *using Java annotations or XML*. Are you using Java annotations or XML to replace--><!--explicit transaction demarcation API calls, etc. OR are you saying the Spring container is using these?
either Java annotations or XML.<!--Reword last part of preceding sentence to clarify *what* is *using Java annotations or XML*. Are you using Java annotations or XML to replace--><!--explicit transaction demarcation API calls, etc. OR are you saying the Spring container is using these?
TR: REVISED, PLS REVIEW.-->This declarative transaction capability allows you
to keep business services free of repetitive transaction demarcation
code and to focus on adding business logic, which is the real value of
@@ -414,22 +418,22 @@ TR: REVISED, PLS REVIEW.-->This declarative transaction capability allows you
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
<lineannotation>&lt;!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --&gt;</lineannotation>
<lineannotation>&lt;!-- SessionFactory, DataSource, etc. omitted --&gt;</lineannotation>
&lt;bean id="transactionManager"
&lt;bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;
&lt;property name="sessionFactory" ref="sessionFactory"/&gt;
&lt;/bean&gt;
&lt;aop:config&gt;
&lt;aop:pointcut id="productServiceMethods"
&lt;aop:pointcut id="productServiceMethods"
expression="execution(* product.ProductService.*(..))"/&gt;
&lt;aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/&gt;
&lt;/aop:config&gt;
@@ -507,20 +511,20 @@ TR: REVISED, PLS REVIEW.-->This declarative transaction capability allows you
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
<lineannotation>&lt;!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --&gt;</lineannotation>
<lineannotation>&lt;!-- SessionFactory, DataSource, etc. omitted --&gt;</lineannotation>
&lt;bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;
&lt;property name="sessionFactory" ref="sessionFactory"/&gt;
&lt;/bean&gt;
&lt;tx:annotation-driven/&gt;
&lt;bean id="myProductService" class="product.SimpleProductService"&gt;
@@ -530,7 +534,7 @@ TR: REVISED, PLS REVIEW.-->This declarative transaction capability allows you
&lt;/beans&gt;</programlisting>
</section>
<section id="orm-hibernate-tx-programmatic">
<section xml:id="orm-hibernate-tx-programmatic">
<title>Programmatic transaction demarcation</title>
<para>You can demarcate transactions in a higher level of the
@@ -596,7 +600,7 @@ TR: REVISED, PLS REVIEW.-->This declarative transaction capability allows you
default but allows configurable rollback policies per method.</para>
</section>
<section id="orm-hibernate-tx-strategies">
<section xml:id="orm-hibernate-tx-strategies">
<title>Transaction management strategies</title>
<para>Both <classname>TransactionTemplate</classname> and
@@ -722,12 +726,12 @@ TR: OK. Reads OK to me, it applies to both. --></para>
<classname>HibernateTransactionManager</classname> class.</para>
</section>
<section id="orm-hibernate-resources">
<title>Comparing container-managed and locally defined resources<!--I've revised to better communicate the point of the section, which I think has to do with --><!--comparing spring's local support for transactions as opposed to container support. Revise as necessary.
<section xml:id="orm-hibernate-resources">
<title>Comparing container-managed and locally defined resources<!--I've revised to better communicate the point of the section, which I think has to do with --><!--comparing spring's local support for transactions as opposed to container support. Revise as necessary.
TR: REVISED, PLS REVIEW. Changed to heading *resources* since it technically could be more than transactions i.e. caching--></title>
<para>You can switch between a container-managed JNDI
<interfacename>SessionFactory</interfacename><!--Clarify whether JNDI SessionFactory refers to container resources; I'm not sure what's being compared.
<interfacename>SessionFactory</interfacename><!--Clarify whether JNDI SessionFactory refers to container resources; I'm not sure what's being compared.
TR: REVISED, PLS REVIEW. Clarified by addin container-managed.--> and a
locally defined one, without having to change a single line of
application code. Whether to keep resource definitions in the container
@@ -744,13 +748,13 @@ TR: REVISED, PLS REVIEW. Clarified by addin container-managed.--> and a
Configured with any strategy other than JTA, transaction support also
works in a stand-alone or test environment. Especially in the typical
case of single-database transactions, Spring's single-resource local
transaction support <!--I wrote *stand-alone transaction support*; if not correct, specify what you mean by *this*.
transaction support <!--I wrote *stand-alone transaction support*; if not correct, specify what you mean by *this*.
TR: REVISED, PLS REVIEW. Changed to single-resource local transaction support.-->is
a lightweight and powerful alternative to JTA. When you use local EJB
stateless session beans to drive transactions, you depend both on an EJB
container and JTA, even if you access only a single database, and only
use stateless session beans to provide declarative transactions through
container-managed transactions. <!--Does the next sentence refer to Spring or non-Spring? Clarify. I'm not sure whether the point of this paragraph and preceding is clear.
container-managed transactions. <!--Does the next sentence refer to Spring or non-Spring? Clarify. I'm not sure whether the point of this paragraph and preceding is clear.
TR: REVISED, PLS REVIEW. It's not very clear. I've revised it. It refers to non-Spring programmatic use of JTA.-->Also,
direct use of JTA programmatically requires a Java EE environment as
well. JTA does not involve only container dependencies in terms of JTA
@@ -787,7 +791,7 @@ TR: REVISED, PLS REVIEW. It's not very clear. I've revised it. It refers to non-
only adds value when used in conjunction with EJBs.</para>
</section>
<section id="orm-hibernate-invalid-jdbc-access-error">
<section xml:id="orm-hibernate-invalid-jdbc-access-error">
<title>Spurious application server warnings with Hibernate</title>
<para>In some JTA environments with very strict
@@ -815,7 +819,7 @@ TR: REVISED, PLS REVIEW. It's not very clear. I've revised it. It refers to non-
obtaining the JTA
<interfacename>PlatformTransactionManager</interfacename> object
(presumably from JNDI through
<literal>JndiObjectFactoryBean/<literal>&lt;jee:jndi-lookup&gt;</literal></literal>)
<literal>JndiObjectFactoryBean</literal> or <literal>&lt;jee:jndi-lookup&gt;</literal>)
and feeding it, for example, to Spring's
<classname>JtaTransactionManager</classname>, then the easiest way
is to specify a reference to the bean defining this JTA
@@ -830,7 +834,7 @@ TR: REVISED, PLS REVIEW. It's not very clear. I've revised it. It refers to non-
<para>More likely you do not already have the JTA
<interfacename>PlatformTransactionManager</interfacename> instance,
because Spring's <classname>JtaTransactionManager</classname> can
find it itself. <!--Re preceding sentence, if this is the case, then why would you need to do what first bullet describes?
find it itself. <!--Re preceding sentence, if this is the case, then why would you need to do what first bullet describes?
TR: OK AS IS. This is very container dependent, and either case is possible.-->Thus
you need to configure Hibernate to look up JTA
<interfacename>PlatformTransactionManager</interfacename> directly.
@@ -863,7 +867,7 @@ TR: OK AS IS. This is very container dependent, and either case is possible.-->T
<listitem>
<para>Among other activities, this synchronization<!--Identify *this*. TR: REVISED, PLS REVIEW. Added "synchronization"--> can
trigger a callback by Spring to Hibernate, through Hibernate's
<literal>afterTransactionCompletion</literal> callback <!--Preceding line, is *afterTransactionCompletion* callback the same as *afterCompletion* callback in step 2? If so, revise so --><!--there is no redundancy, or at least refer to the two callbacks in the same way.
<literal>afterTransactionCompletion</literal> callback <!--Preceding line, is *afterTransactionCompletion* callback the same as *afterCompletion* callback in step 2? If so, revise so --><!--there is no redundancy, or at least refer to the two callbacks in the same way.
TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletion*) and the other is Hibernate's (*afterTransactionCompletion*)-->(used
to clear the Hibernate cache), followed by an explicit
<literal>close()</literal> call on the Hibernate Session, which
@@ -918,7 +922,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
</section>
</section>
<section id="orm-jdo">
<section xml:id="orm-jdo">
<title>JDO</title>
<para>Spring supports the standard JDO 2.0 and 2.1 APIs as data access
@@ -926,7 +930,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
corresponding integration classes reside in the
<literal>org.springframework.orm.jdo</literal> package.</para>
<section id="orm-jdo-setup">
<section xml:id="orm-jdo-setup">
<title><interfacename>PersistenceManagerFactory</interfacename>
setup</title>
@@ -955,8 +959,8 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
usually supports a Spring-defined JDBC
<interfacename>DataSource</interfacename>, passed into the
<classname>connectionFactory</classname> property. For example, for the
open source JDO implementation DataNucleus (formerly JPOX) (<ulink
url="http://www.datanucleus.org/">http://www.datanucleus.org/</ulink>),
open source JDO implementation DataNucleus (formerly JPOX) (<link
xl:href="http://www.datanucleus.org/">http://www.datanucleus.org/</link>),
this is the XML configuration of the
<interfacename>PersistenceManagerFactory</interfacename>
implementation:<!--complete the intro sentence; what does this example show? What is its purpose? TR: REVISED, PLS REVIEW.--></para>
@@ -981,8 +985,8 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
<interfacename>PersistenceManagerFactory</interfacename> in the JNDI
environment of a Java EE application server, usually through the JCA
connector provided by the particular JDO implementation. Spring's
standard <literal>JndiObjectFactoryBean /
<literal>&lt;jee:jndi-lookup&gt;</literal></literal> can be used to
standard <literal>JndiObjectFactoryBean</literal> or
<literal>&lt;jee:jndi-lookup&gt;</literal> can be used to
retrieve and expose such a
<interfacename>PersistenceManagerFactory</interfacename>. However,
outside an EJB context, no real benefit exists in holding the
@@ -992,7 +996,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
there apply to JDO as well.</para>
</section>
<section id="orm-jdo-daos-straight">
<section xml:id="orm-jdo-daos-straight">
<title>Implementing DAOs based on the plain JDO API</title>
<para>DAOs can also be written directly against plain JDO API, without
@@ -1012,7 +1016,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
PersistenceManager pm = this.persistenceManagerFactory.getPersistenceManager();
try {
Query query = pm.newQuery(Product.class, "category = pCategory");
query.declareParameters("String pCategory");
query.declareParameters("String pCategory");
return query.execute(category);
}
finally {
@@ -1083,7 +1087,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
public Collection loadProductsByCategory(String category) {
PersistenceManager pm = this.persistenceManagerFactory.getPersistenceManager();
Query query = pm.newQuery(Product.class, "category = pCategory");
query.declareParameters("String pCategory");
query.declareParameters("String pCategory");
return query.execute(category);
}
}</programlisting>
@@ -1130,7 +1134,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
<exceptionname>DataAccessException</exceptionname> (if desired).</para>
</section>
<section id="orm-jdo-tx">
<section xml:id="orm-jdo-tx">
<title>Transaction management</title>
<note>
@@ -1150,11 +1154,11 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;bean id="myTxManager" class="org.springframework.orm.jdo.JdoTransactionManager"&gt;
@@ -1200,7 +1204,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
case for JDBC-based JDO 2.0 implementations by default.</para>
</section>
<section id="orm-jdo-dialect">
<section xml:id="orm-jdo-dialect">
<title><interfacename>JdoDialect</interfacename></title>
<para>As an advanced feature, both <classname>JdoTemplate</classname>
@@ -1250,25 +1254,25 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
</section>
</section>
<section id="orm-jpa">
<section xml:id="orm-jpa">
<title>JPA</title>
<para>The Spring JPA, available under the
<literal>org.springframework.orm.jpa</literal> package, offers
comprehensive support for the <ulink
url="http://java.sun.com/developer/technicalArticles/J2EE/jpa/index.html">Java
Persistence API</ulink> in a similar manner to the integration with
comprehensive support for the <link
xl:href="http://java.sun.com/developer/technicalArticles/J2EE/jpa/index.html">Java
Persistence API</link> in a similar manner to the integration with
Hibernate or JDO, while being aware of the underlying implementation in
order to provide additional features.</para>
<section id="orm-jpa-setup">
<section xml:id="orm-jpa-setup">
<title>Three options for JPA setup in a Spring environment</title>
<para>The Spring JPA support offers three ways of setting up the JPA
<interfacename>EntityManagerFactory</interfacename> that will be used by
the application to obtain an entity manager.<!--Define and give purpose of JPA EntityManagerFactory. TR: REVISED, PLS REVIEW.--></para>
<section id="orm-jpa-setup-lemfb">
<section xml:id="orm-jpa-setup-lemfb">
<title><classname>LocalEntityManagerFactoryBean</classname></title>
<note>
@@ -1279,7 +1283,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
<para>The <classname>LocalEntityManagerFactoryBean</classname> creates
an <interfacename>EntityManagerFactory</interfacename> suitable for
simple deployment environments where the application uses only JPA for
data access. <!--Note says use option only for stand-alone apps and testing; does that conflict with preceding line re data access?
data access. <!--Note says use option only for stand-alone apps and testing; does that conflict with preceding line re data access?
TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA
<interfacename>PersistenceProvider</interfacename> autodetection
mechanism (according to JPA's Java SE bootstrapping) and, in most
@@ -1304,7 +1308,7 @@ TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA
designed.</para>
</section>
<section id="orm-jpa-setup-jndi">
<section xml:id="orm-jpa-setup-jndi">
<title>Obtaining an <classname>EntityManagerFactory</classname> from
JNDI</title>
@@ -1352,7 +1356,7 @@ TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA
<literal>@PersistenceContext</literal> annotations.</para>
</section>
<section id="orm-jpa-setup-lcemfb">
<section xml:id="orm-jpa-setup-lcemfb">
<title><classname>LocalContainerEntityManagerFactoryBean</classname></title>
<note>
@@ -1377,14 +1381,14 @@ TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA
<interfacename>LocalContainerEntityManagerFactoryBean</interfacename>:<!--The following examples shows what? What's its purpose? TR: REVISED, PLS REVIEW.--></para>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
&lt;property name="dataSource" ref="someDataSource"/&gt;
&lt;property name="loadTimeWeaver"&gt;
&lt;bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>The following example shows a typical
@@ -1419,7 +1423,7 @@ TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA
configuration within the application. It supports links to an existing
JDBC <interfacename>DataSource</interfacename>, supports both local
and global transactions, and so on. However, it also imposes
requirements on the runtime environment, such as the availability <!--Clarify: first says it imposes *requirements* but says such as *the availability* of a weaving-capable Classloader. Revise to say--><!--whether you are *required* to use this when persistence provider demands byte-code transformation. i.e. what is the *requirement* here?
requirements on the runtime environment, such as the availability <!--Clarify: first says it imposes *requirements* but says such as *the availability* of a weaving-capable Classloader. Revise to say--><!--whether you are *required* to use this when persistence provider demands byte-code transformation. i.e. what is the *requirement* here?
TR: OK AS IS. The requirement is to provide the classloader for the runtime environment, if necessary - this is configured outside of Spring.-->of
a weaving-capable class loader if the persistence provider demands
byte-code transformation.</para>
@@ -1454,8 +1458,8 @@ TR: OK AS IS. The requirement is to provide the classloader for the runtime envi
<interfacename>ClassTransformer</interfacename> instances to be
plugged in a specific manner, depending whether the environment is a
web container or application server. <!--Preceding: is this what you mean? Avoid slashes (web container/application server); slashes mean different things depending on context.--><!--Revise if necessary. TR: OK.-->
Hooking <literal>ClassTransformers</literal> through a Java 5 <ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/package-summary.html">agent</ulink>
Hooking <literal>ClassTransformers</literal> through a Java 5 <link
xl:href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/package-summary.html">agent</link>
typically is not efficient. The agents work against the
<emphasis>entire virtual machine</emphasis> and inspect
<emphasis>every</emphasis> class that is loaded, which is usually
@@ -1468,23 +1472,23 @@ TR: OK AS IS. The requirement is to provide the classloader for the runtime envi
applied only <emphasis>per class loader</emphasis> and not per
VM.</para>
<para>Refer to <xref linkend="aop-aj-ltw-spring" /> in the AOP chapter for more insight regarding the
<interfacename>LoadTimeWeaver</interfacename> implementations and their setup, either generic or customized to
<para>Refer to <xref linkend="aop-aj-ltw-spring" /> in the AOP chapter for more insight regarding the
<interfacename>LoadTimeWeaver</interfacename> implementations and their setup, either generic or customized to
various platforms (such as Tomcat, WebLogic, OC4J, GlassFish, Resin and JBoss).</para>
<para>As described in the aforementioned section, you can configure a context-wide <interfacename>LoadTimeWeaver</interfacename>
using the <interfacename>@EnableLoadTimeWeaving</interfacename> annotation of <literal>context:load-time-weaver</literal> XML element.
Such a global weaver is picked up by all JPA <classname>LocalContainerEntityManagerFactoryBeans</classname>
automatically. This is the preferred way of setting up a load-time weaver, delivering autodetection of the platform
<para>As described in the aforementioned section, you can configure a context-wide <interfacename>LoadTimeWeaver</interfacename>
using the <interfacename>@EnableLoadTimeWeaving</interfacename> annotation of <literal>context:load-time-weaver</literal> XML element.
Such a global weaver is picked up by all JPA <classname>LocalContainerEntityManagerFactoryBeans</classname>
automatically. This is the preferred way of setting up a load-time weaver, delivering autodetection of the platform
(WebLogic, OC4J, GlassFish, Tomcat, Resin, JBoss or VM agent) and automatic propagation of the weaver to all weaver-aware beans:</para>
<programlisting language="xml">&lt;context:load-time-weaver/&gt;
<programlisting language="xml">&lt;context:load-time-weaver/&gt;
&lt;bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
...
&lt;/bean&gt;</programlisting>
<para> However, if needed, one can manually specify a dedicated weaver through the <literal>loadTimeWeaver</literal> property:</para>
<para> However, if needed, one can manually specify a dedicated weaver through the <literal>loadTimeWeaver</literal> property:</para>
<programlisting language="xml">&lt;bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
&lt;property name="loadTimeWeaver"&gt;
@@ -1493,23 +1497,23 @@ TR: OK AS IS. The requirement is to provide the classloader for the runtime envi
&lt;/bean&gt;</programlisting>
<para>No matter how the LTW is configured, using this technique, JPA applications relying on
instrumentation can run in the target platform (ex: Tomcat) without needing an agent.
This is important especially when the hosting applications rely on different JPA implementations
instrumentation can run in the target platform (ex: Tomcat) without needing an agent.
This is important especially when the hosting applications rely on different JPA implementations
because the JPA transformers are applied only at class loader level and thus are
isolated from each other.</para>
<!--
<note>
<!--
<note>
<para>If you use TopLink Essentials as a JPA provider under
Tomcat, place the toplink-essentials JAR under
<emphasis>$CATALINA_HOME</emphasis>/shared/lib folder instead of
inside your war.--><!--Revise: *instead of placing the JAR under your WAR*, OR *instead of placing WAR under $CATALINA_HOME/etc*?
inside your war.--><!--Revise: *instead of placing the JAR under your WAR*, OR *instead of placing WAR under $CATALINA_HOME/etc*?
TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
</note>
-->
-->
</section>
<section id="orm-jpa-multiple-pu">
<section xml:id="orm-jpa-multiple-pu">
<title>Dealing with multiple persistence units</title>
<para>For applications that rely on multiple persistence units
@@ -1560,7 +1564,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
</section>
</section>
<section id="orm-jpa-straight">
<section xml:id="orm-jpa-straight">
<title>Implementing DAOs based on plain JPA</title>
<note>
@@ -1661,7 +1665,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
public Collection loadProductsByCategory(String category) {
Query query = em.createQuery("from Product as p where p.category = :category");
query.setParameter("category", category);
return query.getResultList();
return query.getResultList();
}
}</programlisting>
@@ -1712,7 +1716,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
developers.</para>
</section>
<section id="orm-jpa-tx">
<section xml:id="orm-jpa-tx">
<title>Transaction Management</title>
<note>
@@ -1731,11 +1735,11 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
@@ -1745,7 +1749,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
&lt;bean id="myProductService" class="product.ProductServiceImpl"&gt;
&lt;property name="productDao" ref="myProductDao"/&gt;
&lt;/bean&gt;
&lt;aop:config&gt;
&lt;aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/&gt;
&lt;aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/&gt;
@@ -1772,7 +1776,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
<interfacename>JpaDialect</interfacename> mechanism.</para>
</section>
<section id="orm-jpa-dialect">
<section xml:id="orm-jpa-dialect">
<title><interfacename>JpaDialect</interfacename></title>
<para>As an advanced feature <classname>JpaTemplate</classname>,
@@ -1820,7 +1824,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
</section>
</section>
<section id="orm-ibatis">
<section xml:id="orm-ibatis">
<title>iBATIS SQL Maps</title>
<para>The iBATIS support in the Spring Framework much resembles the JDBC
@@ -1842,7 +1846,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
longer provided.<!--directed where? TR: REVISED, PLS REVIEW.--></para>
</note>
<section id="orm-ibatis-setup">
<section xml:id="orm-ibatis-setup">
<title>Setting up the <classname>SqlMapClient</classname></title>
<para>Using iBATIS SQL Maps involves creating SqlMap configuration files
@@ -1854,12 +1858,12 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
<programlisting language="xml">public class Account {
private String name;
private String email;
private String email;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@@ -1873,7 +1877,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
}
}</programlisting>
<para>To map this <classname>Account</classname> class<!--*previous account class*:Identify the account class and the section you're talking about
<para>To map this <classname>Account</classname> class<!--*previous account class*:Identify the account class and the section you're talking about
TR: REVISED, PLS REVIEW. The Account class was part of the iBATIS 1.0 examples that were dropped a long time ago. No one has complained.
Makes you wonder if anyone actually reads thes docs :)--> with iBATIS 2.x we
need to create the following SQL map
@@ -1934,7 +1938,7 @@ Makes you wonder if anyone actually reads thes docs :)--> with iBATIS 2.x we
&lt;/beans&gt;</programlisting>
</section>
<section id="orm-ibatis-template">
<section xml:id="orm-ibatis-template">
<title>Using <classname>SqlMapClientTemplate</classname> and
<classname>SqlMapClientDaoSupport</classname></title>
@@ -1999,7 +2003,7 @@ Makes you wonder if anyone actually reads thes docs :)--> with iBATIS 2.x we
hierarchy.</para>
</section>
<section id="orm-ibatis-straight">
<section xml:id="orm-ibatis-straight">
<title>Implementing DAOs based on plain iBATIS API</title>
<para>DAOs can also be written against plain iBATIS API, without any
@@ -2008,9 +2012,9 @@ Makes you wonder if anyone actually reads thes docs :)--> with iBATIS 2.x we
corresponding DAO implementation:</para>
<programlisting language="java">public class SqlMapAccountDao implements AccountDao {
private SqlMapClient sqlMapClient;
public void setSqlMapClient(SqlMapClient sqlMapClient) {
this.sqlMapClient = sqlMapClient;
}

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="overview"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="overview">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Introduction to Spring Framework</title>
<para>Spring Framework is a Java platform that provides comprehensive
@@ -39,10 +43,10 @@
</listitem>
</itemizedlist>
<section id="overview-dependency-injection">
<section xml:id="overview-dependency-injection">
<title>Dependency Injection and Inversion of Control</title>
<sidebar id="background-ioc">
<sidebar xml:id="background-ioc">
<title>Background</title>
<para><quote><emphasis>The question is, what aspect of control are
@@ -51,8 +55,8 @@
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>
<para>For insight into IoC and DI, refer to Fowler's article at <link
xl:href="http://martinfowler.com/articles/injection.html">http://martinfowler.com/articles/injection.html</link>.</para>
</sidebar>
<para>Java applications -- a loose term that runs the gamut from
@@ -86,7 +90,7 @@ TR: This section doesn't read well and I think we should try to rewrite it.-->Nu
engineer robust, <emphasis>maintainable</emphasis> applications.</para>
</section>
<section id="overview-modules">
<section xml:id="overview-modules">
<title>Modules</title>
<para>The Spring Framework consists of features organized into about 20
@@ -108,7 +112,7 @@ TR: This section doesn't read well and I think we should try to rewrite it.-->Nu
<caption><para>Overview of the Spring Framework</para></caption>
</mediaobject></para>
<section id="overview-core-container">
<section xml:id="overview-core-container">
<title>Core Container</title>
<para>The <link linkend="beans-introduction"><emphasis>Core
@@ -150,7 +154,7 @@ TR: This section doesn't read well and I think we should try to rewrite it.-->Nu
aggregations.</para>
</section>
<section id="overview-data-access">
<section xml:id="overview-data-access">
<title>Data Access/Integration</title>
<para>The <emphasis>Data Access/Integration</emphasis> layer consists of
@@ -184,7 +188,7 @@ TR: This section doesn't read well and I think we should try to rewrite it.-->Nu
Java objects)</emphasis>.</para>
</section>
<section id="overview-web">
<section xml:id="overview-web">
<title>Web</title>
<para>The <emphasis>Web</emphasis> layer consists of the Web,
@@ -201,7 +205,7 @@ TR: This section doesn't read well and I think we should try to rewrite it.-->Nu
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?
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
@@ -215,7 +219,7 @@ It sounds important.--><!--TR: REVISED, PLS REVIEW.--></para>
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 id="overview-aop-instrumentation">
<section xml:id="overview-aop-instrumentation">
<title>AOP and Instrumentation</title>
<para>Spring's <link
@@ -237,7 +241,7 @@ TR: OK. Added to diagram.--></para>
certain application servers.</para>
</section>
<section id="overview-testing">
<section xml:id="overview-testing">
<title>Test</title>
<para>The <emphasis>Test</emphasis> module supports the testing of
@@ -248,7 +252,7 @@ TR: OK. Added to diagram.--></para>
</section>
</section>
<section id="overview-usagescenarios">
<section xml:id="overview-usagescenarios">
<title>Usage scenarios</title>
<para>The building blocks described previously make Spring a logical
@@ -353,7 +357,7 @@ TR: OK. Added to diagram.--></para>
scalable, fail-safe web applications that might need declarative
security.</para>
<section id="dependency-management">
<section xml:id="dependency-management">
<title>Dependency Management and Naming Conventions</title>
<para>Dependency management and dependency injection are different
@@ -386,8 +390,8 @@ TR: OK. Added to diagram.--></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>.
<para>On the community download site <link
xl:href="http://www.springsource.org/downloads/community">http://www.springsource.org/downloads/community</link>.
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
@@ -417,8 +421,8 @@ TR: OK. Added to diagram.--></para>
(<code>org.springframework.*-&lt;version&gt;.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>
<code>com.springsource</code>. See the <link
xl:href="http://www.springsource.com/repository/app/faq">FAQ</link>
for more information.</para>
</listitem>
@@ -553,8 +557,8 @@ TR: OK. Added to diagram.--></para>
<entry>Various</entry>
<entry><ulink
url="http://www.springsource.com/repository">http://www.springsource.com/repository</ulink></entry>
<entry><link
xl:href="http://www.springsource.com/repository">http://www.springsource.com/repository</link></entry>
</row>
<row>
@@ -570,7 +574,7 @@ TR: OK. Added to diagram.--></para>
</tgroup>
</table></para>
<section id="overview-spring-dependencies">
<section xml:id="overview-spring-dependencies">
<title>Spring Dependencies and Depending on Spring</title>
<para>Although Spring provides integration and support for a huge
@@ -590,7 +594,7 @@ TR: OK. Added to diagram.--></para>
our samples mostly use Maven.</para>
</section>
<section id="overview-maven-dependency-management">
<section xml:id="overview-maven-dependency-management">
<title>Maven Dependency Management</title>
<para>If you are using Maven for dependency management you don't even
@@ -671,18 +675,18 @@ TR: OK. Added to diagram.--></para>
<para>If you are managing your dependencies by hand, the URL in the
repository declaration above is not browsable, but there is a user
interface at <ulink
url="http://www.springsource.com/repository">http://www.springsource.com/repository</ulink>
interface at <link
xl:href="http://www.springsource.com/repository">http://www.springsource.com/repository</link>
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 id="overview-ivy-dependency-management">
<section xml:id="overview-ivy-dependency-management">
<title>Ivy Dependency Management</title>
<para>If you prefer to use <ulink
url="http://ant.apache.org/ivy">Ivy</ulink> to manage dependencies
<para>If you prefer to use <link
xl:href="http://ant.apache.org/ivy">Ivy</link> to manage dependencies
then there are similar names and configuration options. </para>
<para>To configure Ivy to point to the SpringSource EBR add the
@@ -690,7 +694,7 @@ TR: OK. Added to diagram.--></para>
<filename>ivysettings.xml</filename>:</para>
<programlisting>&lt;resolvers&gt;
&lt;url name="com.springsource.repository.bundles.release"&gt;
&lt;ivy pattern="http://repository.springsource.com/ivy/bundles/release/
@@ -705,7 +709,7 @@ TR: OK. Added to diagram.--></para>
&lt;ivy pattern="http://repository.springsource.com/ivy/bundles/external/
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" /&gt;
&lt;artifact pattern="http://repository.springsource.com/ivy/bundles/external/
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" /&gt;
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" /&gt;
&lt;/url&gt;
@@ -721,12 +725,12 @@ TR: OK. Added to diagram.--></para>
include in your dependencies section. For example (in
<filename>ivy.xml</filename>): </para>
<programlisting>&lt;dependency org="org.springframework"
<programlisting>&lt;dependency org="org.springframework"
name="org.springframework.core" rev="3.0.0.RELEASE" conf="compile-&gt;runtime"/&gt;</programlisting>
</section>
</section>
<section id="overview-logging">
<section xml:id="overview-logging">
<title>Logging</title>
<para>Logging is a very important dependency for Spring because a) it is
@@ -763,15 +767,15 @@ TR: OK. Added to diagram.--></para>
application works and logs happily to the console out of the box in most
situations, and that's important.</para>
<section id="overview-not-using-commons-logging">
<section xml:id="overview-not-using-commons-logging">
<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
first choice would probably be the Simple Logging Facade for Java (<link
xl:href="http://www.slf4j.org">SLF4J</link>), which is also used by a lot
of other tools that people use with Spring inside their
applications.</para>
@@ -801,94 +805,94 @@ TR: OK. Added to diagram.--></para>
alternative implementation of JCL using SLF4J as an example.</para>
</section>
<section id="overview-logging-slf4j">
<section xml:id="overview-logging-slf4j">
<title>Using SLF4J</title>
<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>&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-context&lt;/artifactId&gt;
&lt;version&gt;3.0.0.RELEASE&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;exclusions&gt;
&lt;exclusion&gt;
&lt;groupId&gt;commons-logging&lt;/groupId&gt;
&lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
&lt;/exclusion&gt;
&lt;/exclusions&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;jcl-over-slf4j&lt;/artifactId&gt;
&lt;version&gt;1.5.8&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
&lt;version&gt;1.5.8&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-log4j12&lt;/artifactId&gt;
&lt;version&gt;1.5.8&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;log4j&lt;/groupId&gt;
&lt;artifactId&gt;log4j&lt;/artifactId&gt;
&lt;version&gt;1.2.14&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt; </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 <link
xl:href="http://logback.qos.ch">Logback</link>. This removes the extra
binding step because Logback implements SLF4J directly, so you only need
to depend on two libraries not four (<code>jcl-over-slf4j</code> and
<code>logback</code>). If you do that you might also need to exclude the
slf4j-api dependency from other external dependencies (not Spring),
because you only want one version of that API on the classpath.</para>
</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>&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-context&lt;/artifactId&gt;
&lt;version&gt;3.0.0.RELEASE&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;exclusions&gt;
&lt;exclusion&gt;
&lt;groupId&gt;commons-logging&lt;/groupId&gt;
&lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
&lt;/exclusion&gt;
&lt;/exclusions&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;jcl-over-slf4j&lt;/artifactId&gt;
&lt;version&gt;1.5.8&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
&lt;version&gt;1.5.8&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.slf4j&lt;/groupId&gt;
&lt;artifactId&gt;slf4j-log4j12&lt;/artifactId&gt;
&lt;version&gt;1.5.8&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;log4j&lt;/groupId&gt;
&lt;artifactId&gt;log4j&lt;/artifactId&gt;
&lt;version&gt;1.2.14&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt; </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 libraries not four (<code>jcl-over-slf4j</code> and
<code>logback</code>). If you do that you might also need to exclude the
slf4j-api dependency from other external dependencies (not Spring),
because you only want one version of that API on the classpath.</para>
<section id="overview-logging-log4j">
<section xml:id="overview-logging-log4j">
<title>Using Log4J</title>
<para>Many people use <ulink
url="http://logging.apache.org/log4j">Log4j</ulink> as a logging
<para>Many people use <link
xl:href="http://logging.apache.org/log4j">Log4j</link> 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
@@ -928,7 +932,7 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m
log4j.category.org.springframework.beans.factory=DEBUG</programlisting>
<section id="overview-native-jcl">
<section xml:id="overview-native-jcl">
<title>Runtime Containers with Native JCL</title>
<para>Many people run their Spring applications in a container that

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="oxm"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="oxm">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Marshalling XML using O/X Mappers</title>
<section id="oxm-introduction">
<section xml:id="oxm-introduction">
<title>Introduction</title>
<para>
In this chapter, we will describe Spring's Object/XML Mapping support. Object/XML Mapping, or O/X mapping
@@ -13,7 +17,7 @@
known as XML Marshalling, or XML Serialization. This chapter uses these terms interchangeably.
</para>
<para>
Within the field of O/X mapping, a <emphasis>marshaller</emphasis> is responsible for serializing an
Within the field of O/X mapping, a <emphasis>marshaller</emphasis> is responsible for serializing an
object (graph) to XML. In similar fashion, an <emphasis>unmarshaller</emphasis> deserializes the XML to an
object graph. This XML can take the form of a DOM document, an input or output stream, or a SAX handler.
</para>
@@ -30,12 +34,12 @@
<formalpara>
<title>Consistent Interfaces</title>
<para>
Spring's O/X mapping operates through two global interfaces: the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
These abstractions allow you to switch O/X mapping
frameworks with relative ease, with little or no changes required on the classes that do the
marshalling. This approach has the additional benefit of making it possible to do XML marshalling with
a mix-and-match approach (e.g. some marshalling performed using JAXB, other using XMLBeans) in a
Spring's O/X mapping operates through two global interfaces: the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
These abstractions allow you to switch O/X mapping
frameworks with relative ease, with little or no changes required on the classes that do the
marshalling. This approach has the additional benefit of making it possible to do XML marshalling with
a mix-and-match approach (e.g. some marshalling performed using JAXB, other using XMLBeans) in a
non-intrusive fashion, leveraging the strength of each technology.
</para>
</formalpara>
@@ -48,18 +52,18 @@
</para>
</formalpara>
</section>
<section id="oxm-marshaller-unmarshaller">
<section xml:id="oxm-marshaller-unmarshaller">
<title>Marshaller and Unmarshaller</title>
<para>
As stated in the introduction, a <emphasis>marshaller</emphasis> serializes an object to XML, and an
<emphasis>unmarshaller</emphasis> deserializes XML stream to an object. In this section, we will describe
the two Spring interfaces used for this purpose.
</para>
<section id="oxm-marshaller">
<section xml:id="oxm-marshaller">
<title>Marshaller</title>
<para>
Spring abstracts all marshalling operations behind the
<interfacename>org.springframework.oxm.Marshaller</interfacename> interface, the main methods of which
Spring abstracts all marshalling operations behind the
<interfacename>org.springframework.oxm.Marshaller</interfacename> interface, the main methods of which
is listed below.
<programlisting language="java"><![CDATA[
public interface Marshaller {
@@ -71,7 +75,7 @@ public interface Marshaller {
throws XmlMappingException, IOException;
}]]></programlisting>
The <interfacename>Marshaller</interfacename> interface has one main method, which marshals the given
object to a given <interfacename>javax.xml.transform.Result</interfacename>. Result is a tagging
object to a given <interfacename>javax.xml.transform.Result</interfacename>. Result is a tagging
interface that basically represents an XML output abstraction: concrete implementations wrap various XML
representations, as indicated in the table below.
<informaltable>
@@ -104,8 +108,8 @@ public interface Marshaller {
</informaltable>
<note>
<para>
Although the <methodname>marshal()</methodname> method accepts a plain object as its first
parameter, most <classname>Marshaller</classname> implementations cannot handle arbitrary
Although the <methodname>marshal()</methodname> method accepts a plain object as its first
parameter, most <classname>Marshaller</classname> implementations cannot handle arbitrary
objects. Instead, an object class must be mapped in a mapping file, marked with an annotation,
registered with the marshaller, or have a common base class. Refer to the further sections
in this chapter to determine how your O/X technology of choice manages this.
@@ -113,10 +117,10 @@ public interface Marshaller {
</note>
</para>
</section>
<section id="oxm-unmarshaller">
<section xml:id="oxm-unmarshaller">
<title>Unmarshaller</title>
<para>
Similar to the <interfacename>Marshaller</interfacename>, there is the
Similar to the <interfacename>Marshaller</interfacename>, there is the
<interfacename>org.springframework.oxm.Unmarshaller</interfacename> interface.
<programlisting language="java"><![CDATA[
public interface Unmarshaller {
@@ -127,7 +131,7 @@ public interface Unmarshaller {
Object unmarshal(Source source)
throws XmlMappingException, IOException;
}]]></programlisting>
This interface also has one method, which reads from the given
This interface also has one method, which reads from the given
<interfacename>javax.xml.transform.Source</interfacename> (an XML input abstraction), and returns the
object read. As with Result, Source is a tagging interface that has three concrete implementations. Each
wraps a different XML representation, as indicated in the table below.
@@ -163,14 +167,14 @@ public interface Unmarshaller {
</tgroup>
</informaltable>
</para>
<para>
Even though there are two separate marshalling interfaces (<interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename>), all implementations found in Spring-WS implement both in
one class. This means that you can wire up one marshaller class and refer to it both as a marshaller and an
unmarshaller in your <filename>applicationContext.xml</filename>.
</para>
</section>
<para>
Even though there are two separate marshalling interfaces (<interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename>), all implementations found in Spring-WS implement both in
one class. This means that you can wire up one marshaller class and refer to it both as a marshaller and an
unmarshaller in your <filename>applicationContext.xml</filename>.
</para>
<section id="oxm-xmlmappingexception">
<section xml:id="oxm-xmlmappingexception">
<title>XmlMappingException</title>
<para>
Spring converts exceptions from the underlying O/X mapping tool to its own exception hierarchy with the
@@ -194,7 +198,8 @@ public interface Unmarshaller {
O/X Mapping exception hierarchy
</para>
</caption>
</mediaobject>
<mediaobject>
<imageobject role="html">
<imagedata align="center" fileref="images/oxm-exceptions.png"
format="PNG" width="400"/>
@@ -208,7 +213,7 @@ public interface Unmarshaller {
</para>
</section>
</section>
<section id="oxm-usage">
<section xml:id="oxm-usage">
<title>Using Marshaller and Unmarshaller</title>
<para>
Spring's OXM can be used for a wide variety of situations. In the following example, we will use it to
@@ -317,14 +322,14 @@ public class Application {
]]></programlisting>
</para>
</section>
<section id="oxm-schema-based-config">
<title>XML Schema-based Configuration</title>
<para>
Marshallers could be configured more concisely using tags from the OXM namespace.
To make these tags available, the appropriate schema has to be referenced first in the preamble of the XML configuration file.
Note the 'oxm' related text below:
</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<section xml:id="oxm-schema-based-config">
<title>XML Schema-based Configuration</title>
<para>
Marshallers could be configured more concisely using tags from the OXM namespace.
To make these tags available, the appropriate schema has to be referenced first in the preamble of the XML configuration file.
Note the 'oxm' related text below:
</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
]]><emphasis role="bold"><![CDATA[xmlns:oxm="http://www.springframework.org/schema/oxm"]]></emphasis>
@@ -333,48 +338,48 @@ public class Application {
]]><emphasis role="bold"><![CDATA[http://www.springframework.org/schema/oxm
]]><![CDATA[http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd"]]></emphasis><![CDATA[>
]]></programlisting>
<para>
Currently, the following tags are available:
<itemizedlist>
<listitem>
<para><link linkend="oxm-jaxb2-xsd"><literal>jaxb2-marshaller</literal></link></para>
</listitem>
<listitem>
<para><link linkend="oxm-xmlbeans-xsd"><literal>xmlbeans-marshaller</literal></link></para>
</listitem>
<listitem>
<para><link linkend="oxm-jibx-xsd"><literal>jibx-marshaller</literal></link></para>
</listitem>
</itemizedlist>
</para>
<para>
Each tag will be explained in its respective marshaller's section. As an example though, here is how
the configuration of a JAXB2 marshaller might look like:
</para>
<programlisting language="xml"><![CDATA[<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>]]></programlisting>
</section>
<section id="oxm-jaxb">
<para>
Currently, the following tags are available:
<itemizedlist>
<listitem>
<para><link linkend="oxm-jaxb2-xsd"><literal>jaxb2-marshaller</literal></link></para>
</listitem>
<listitem>
<para><link linkend="oxm-xmlbeans-xsd"><literal>xmlbeans-marshaller</literal></link></para>
</listitem>
<listitem>
<para><link linkend="oxm-jibx-xsd"><literal>jibx-marshaller</literal></link></para>
</listitem>
</itemizedlist>
</para>
<para>
Each tag will be explained in its respective marshaller's section. As an example though, here is how
the configuration of a JAXB2 marshaller might look like:
</para>
<programlisting language="xml"><![CDATA[<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>]]></programlisting>
</section>
<section xml:id="oxm-jaxb">
<title>JAXB</title>
<para>
The JAXB binding compiler translates a W3C XML Schema into one or more Java classes, a
<filename>jaxb.properties</filename> file, and possibly some resource files. JAXB also offers a
The JAXB binding compiler translates a W3C XML Schema into one or more Java classes, a
<filename>jaxb.properties</filename> file, and possibly some resource files. JAXB also offers a
way to generate a schema from annotated Java classes.
</para>
<para>
Spring supports the JAXB 2.0 API as XML marshalling strategies, following the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename>
interfaces described in <xref linkend="oxm-marshaller-unmarshaller"/>. The corresponding integration
interfaces described in <xref linkend="oxm-marshaller-unmarshaller"/>. The corresponding integration
classes reside in the <package>org.springframework.oxm.jaxb</package> package.
</para>
<section id="oxm-jaxb2">
<section xml:id="oxm-jaxb2">
<title>Jaxb2Marshaller</title>
<para>
The <classname>Jaxb2Marshaller</classname> class implements both the Spring
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename>interface. It
requires a context path to operate, which you can set using the <property>contextPath</property>
property. The context path is a list of colon (:) separated Java package names that contain schema
derived classes. It also offers a <property>classesToBeBound</property> property, which allows you to set an array of
classes to be supported by the marshaller. Schema validation is performed by specifying one or more
derived classes. It also offers a <property>classesToBeBound</property> property, which allows you to set an array of
classes to be supported by the marshaller. Schema validation is performed by specifying one or more
schema resource to the bean, like so:
</para>
<programlisting language="xml"><![CDATA[
@@ -384,7 +389,7 @@ public class Application {
<property name="classesToBeBound">
<list>
<value>org.springframework.oxm.jaxb.Flight</value>
<value>org.springframework.oxm.jaxb.Flights</value>
<value>org.springframework.oxm.jaxb.Flights</value>
</list>
</property>
<property name="schema" value="classpath:org/springframework/oxm/schema.xsd"/>
@@ -392,29 +397,29 @@ public class Application {
...
</beans>]]></programlisting>
<section id="oxm-jaxb2-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>jaxb2-marshaller</literal> tag configures a <classname>org.springframework.oxm.jaxb.Jaxb2Marshaller</classname>.
Here is an example:
</para>
<programlisting language="xml"><![CDATA[<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>]]></programlisting>
<para>
Alternatively, the list of classes to bind can be provided to the marshaller via the <literal>class-to-be-bound</literal> child tag:
</para>
<programlisting language="xml"><![CDATA[<oxm:jaxb2-marshaller id="marshaller">
<section xml:id="oxm-jaxb2-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>jaxb2-marshaller</literal> tag configures a <classname>org.springframework.oxm.jaxb.Jaxb2Marshaller</classname>.
Here is an example:
</para>
<programlisting language="xml"><![CDATA[<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>]]></programlisting>
<para>
Alternatively, the list of classes to bind can be provided to the marshaller via the <literal>class-to-be-bound</literal> child tag:
</para>
<programlisting language="xml"><![CDATA[<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Airport"/>
<oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Flight"/>
...
</oxm:jaxb2-marshaller>
]]></programlisting>
<para>
Available attributes are:
]]></programlisting>
<para>
Available attributes are:
<informaltable>
<tgroup cols="3">
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<thead>
<row>
<entry>Attribute</entry>
@@ -436,11 +441,11 @@ public class Application {
</tbody>
</tgroup>
</informaltable>
</para>
</section>
</para>
</section>
</section>
</section>
<section id="oxm-castor">
<section xml:id="oxm-castor">
<title>Castor</title>
<para>
Castor XML mapping is an open source XML binding framework. It allows you to transform the data contained in
@@ -448,15 +453,15 @@ public class Application {
though a mapping file can be used to have more control over the behavior of Castor.
</para>
<para>
For more information on Castor, refer to the <ulink url="http://castor.org/xml-framework.html">
<citetitle>Castor web site</citetitle></ulink>. The Spring integration classes reside in the
For more information on Castor, refer to the <link xl:href="http://castor.org/xml-framework.html">
<citetitle>Castor web site</citetitle></link>. The Spring integration classes reside in the
<package>org.springframework.oxm.castor</package> package.
</para>
<section id="oxm-castor-marshaller">
<section xml:id="oxm-castor-marshaller">
<title>CastorMarshaller</title>
<para>
As with JAXB, the <classname>CastorMarshaller</classname> implements both the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
As with JAXB, the <classname>CastorMarshaller</classname> implements both the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
It can be wired up as follows:
</para>
<programlisting language="xml"><![CDATA[
@@ -467,12 +472,12 @@ public class Application {
</beans>]]></programlisting>
</section>
<section id="oxm-castor-mapping">
<section xml:id="oxm-castor-mapping">
<title>Mapping</title>
<para>
Although it is possible to rely on Castor's default marshalling behavior, it might be necessary to have
more control over it. This can be accomplished using a Castor mapping file. For more information, refer
to <ulink url="http://castor.org/xml-mapping.html">Castor XML Mapping</ulink>.
to <link xl:href="http://castor.org/xml-mapping.html">Castor XML Mapping</link>.
</para>
<para>
The mapping can be set using the <property>mappingLocation</property> resource property, indicated
@@ -488,7 +493,7 @@ public class Application {
</section>
</section>
<section id="oxm-xmlbeans">
<section xml:id="oxm-xmlbeans">
<title>XMLBeans</title>
<para>
XMLBeans is an XML binding tool that has full XML Schema support, and offers full XML Infoset
@@ -497,11 +502,11 @@ public class Application {
<interfacename>XmlObject</interfacename>, and contain XML binding information in them.
</para>
<para>
For more information on XMLBeans, refer to the <ulink url="http://xmlbeans.apache.org/">
<citetitle>XMLBeans web site </citetitle></ulink>. The Spring-WS integration classes reside
For more information on XMLBeans, refer to the <link xl:href="http://xmlbeans.apache.org/">
<citetitle>XMLBeans web site </citetitle></link>. The Spring-WS integration classes reside
in the <package>org.springframework.oxm.xmlbeans</package> package.
</para>
<section id="oxm-xmlbeans-marshaller">
<section xml:id="oxm-xmlbeans-marshaller">
<title>XmlBeansMarshaller</title>
<para>
The <classname>XmlBeansMarshaller</classname>
@@ -523,20 +528,20 @@ public class Application {
and not every <classname>java.lang.Object</classname>.
</para>
</note>
<section id="oxm-xmlbeans-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>xmlbeans-marshaller</literal> tag configures a <classname>org.springframework.oxm.xmlbeans.XmlBeansMarshaller</classname>.
Here is an example:
</para>
<programlisting language="xml"><![CDATA[<oxm:xmlbeans-marshaller id="marshaller"/>]]></programlisting>
<para>
Available attributes are:
<section xml:id="oxm-xmlbeans-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>xmlbeans-marshaller</literal> tag configures a <classname>org.springframework.oxm.xmlbeans.XmlBeansMarshaller</classname>.
Here is an example:
</para>
<programlisting language="xml"><![CDATA[<oxm:xmlbeans-marshaller id="marshaller"/>]]></programlisting>
<para>
Available attributes are:
<informaltable>
<tgroup cols="3">
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<thead>
<row>
<entry>Attribute</entry>
@@ -559,14 +564,14 @@ public class Application {
</tbody>
</tgroup>
</informaltable>
</para>
</section>
</para>
</section>
</section>
</section>
<section id="oxm-jibx">
<section xml:id="oxm-jibx">
<title>JiBX</title>
<para>
The JiBX framework offers a solution similar to that which JDO provides for ORM: a binding definition defines the
@@ -575,18 +580,18 @@ public class Application {
the classes from or to XML.
</para>
<para>
For more information on JiBX, refer to the <ulink url="http://jibx.sourceforge.net/">
<citetitle>JiBX web site</citetitle></ulink>. The Spring integration classes reside in the
For more information on JiBX, refer to the <link xl:href="http://jibx.sourceforge.net/">
<citetitle>JiBX web site</citetitle></link>. The Spring integration classes reside in the
<package>org.springframework.oxm.jibx</package> package.
</para>
<section id="oxm-jibx-marshaller">
<section xml:id="oxm-jibx-marshaller">
<title>JibxMarshaller</title>
<para>
The <classname>JibxMarshaller</classname> class implements both the
The <classname>JibxMarshaller</classname> class implements both the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
To operate, it requires the name of the class to marshal in, which you can set using the
<property>targetClass</property> property. Optionally, you can set the binding name using the
<property>bindingName</property> property. In the next sample, we bind the
<property>bindingName</property> property. In the next sample, we bind the
<classname>Flights</classname> class:
</para>
<programlisting language="xml"><![CDATA[
@@ -603,20 +608,20 @@ public class Application {
multiple classes, you have to configure multiple <classname>JibxMarshaller</classname>s with
different <property>targetClass</property> property values.
</para>
<section id="oxm-jibx-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>jibx-marshaller</literal> tag configures a <classname>org.springframework.oxm.jibx.JibxMarshaller</classname>.
Here is an example:
</para>
<programlisting language="xml"><![CDATA[<oxm:jibx-marshaller id="marshaller" target-class="org.springframework.ws.samples.airline.schema.Flight"/>]]></programlisting>
<para>
Available attributes are:
<section xml:id="oxm-jibx-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>jibx-marshaller</literal> tag configures a <classname>org.springframework.oxm.jibx.JibxMarshaller</classname>.
Here is an example:
</para>
<programlisting language="xml"><![CDATA[<oxm:jibx-marshaller id="marshaller" target-class="org.springframework.ws.samples.airline.schema.Flight"/>]]></programlisting>
<para>
Available attributes are:
<informaltable>
<tgroup cols="3">
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<thead>
<row>
<entry>Attribute</entry>
@@ -643,26 +648,26 @@ public class Application {
</tbody>
</tgroup>
</informaltable>
</para>
</section>
</para>
</section>
</section>
</section>
<section id="oxm-xstream">
<section xml:id="oxm-xstream">
<title>XStream</title>
<para>
XStream is a simple library to serialize objects to XML and back again. It does not require any mapping, and
generates clean XML.
</para>
<para>
For more information on XStream, refer to the <ulink url="http://xstream.codehaus.org/">
<citetitle>XStream web site</citetitle></ulink>. The Spring integration classes reside in the
For more information on XStream, refer to the <link xl:href="http://xstream.codehaus.org/">
<citetitle>XStream web site</citetitle></link>. The Spring integration classes reside in the
<package>org.springframework.oxm.xstream</package> package.
</para>
<section id="oxm-xstream-marshaller">
<section xml:id="oxm-xstream-marshaller">
<title>XStreamMarshaller</title>
<para>
The <classname>XStreamMarshaller</classname> does not require any configuration, and can be configured
in an application context directly. To further customize the XML, you can set an
in an application context directly. To further customize the XML, you can set an
<emphasis>alias map</emphasis>, which consists of string aliases mapped to classes:
</para>
<programlisting language="xml"><![CDATA[
@@ -691,8 +696,8 @@ public class Application {
This will make sure that only the registered classes are eligible for unmarshalling.
</para>
<para>
Additionally, you can register <ulink url="http://static.springsource.org/spring/docs/current/api/org/springframework/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher[])">
custom converters</ulink> to make sure that only your supported classes can be unmarshalled.
Additionally, you can register <link xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher[])">
custom converters</link> to make sure that only your supported classes can be unmarshalled.
</para>
</warning>
<note>

View File

@@ -1,20 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="portlet"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="portlet">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Portlet MVC Framework</title>
<section id="portlet-introduction">
<section xml:id="portlet-introduction">
<title>Introduction</title>
<sidebar>
<title>JSR-168 The Java Portlet Specification</title>
<para>For more general information about portlet development, please
review a whitepaper from Sun entitled
<ulink url="http://developers.sun.com/prodtech/portalserver/reference/techart/jsr168/">"Introduction to JSR 168"</ulink>,
<link xl:href="http://developers.sun.com/prodtech/portalserver/reference/techart/jsr168/">"Introduction to JSR 168"</link>,
and of course the
<ulink url="http://jcp.org/aboutJava/communityprocess/final/jsr168/">JSR-168 Specification</ulink> itself.</para>
<link xl:href="http://jcp.org/aboutJava/communityprocess/final/jsr168/">JSR-168 Specification</link> itself.</para>
</sidebar>
<para>In addition to supporting conventional (servlet-based) Web development,
@@ -78,7 +82,7 @@
<classname>DispatcherPortlet</classname> exposes the current locale in
the same way as <classname>DispatcherServlet</classname>.</para>
<section id="portlet-introduction-controller">
<section xml:id="portlet-introduction-controller">
<title>Controllers - The C in MVC</title>
<para>The default handler is still a very simple
<interfacename>Controller</interfacename> interface, offering just two
@@ -98,7 +102,7 @@
same as in the servlet framework.</para>
</section>
<section id="portlet-introduction-view">
<section xml:id="portlet-introduction-view">
<title>Views - The V in MVC</title>
<para>All the view rendering capabilities of the servlet framework are
used directly via a special bridge servlet named
@@ -109,7 +113,7 @@
within the portlet.</para>
</section>
<section id="portlet-introduction-scope">
<section xml:id="portlet-introduction-scope">
<title>Web-scoped beans</title>
<para>Spring Portlet MVC supports beans whose lifecycle is scoped to the
current HTTP request or HTTP <interfacename>Session</interfacename> (both
@@ -118,7 +122,7 @@
container(s) that Spring Portlet MVC uses. These bean scopes are described
in detail in <xref linkend="beans-factory-scopes-other"/></para>
</section>
<!--
As of Spring 3.0.0.RC1, the PetPortal sample application is not
included in the Spring distribution. Thus the following note is
@@ -135,7 +139,7 @@
-->
</section>
<section id="portlet-dispatcher">
<section xml:id="portlet-dispatcher">
<title>The <classname>DispatcherPortlet</classname></title>
<para>Portlet MVC is a request-driven web MVC framework, designed around
@@ -196,7 +200,7 @@
defaults are provided so you don't have to worry about configuring
them.</para>
<table id="portlet-webappctx-special-beans-tbl">
<table xml:id="portlet-webappctx-special-beans-tbl">
<title>Special beans in the <interfacename>WebApplicationContext</interfacename></title>
<tgroup cols="2">
<colspec colname="c1" colwidth="1*" align="left" />
@@ -291,7 +295,7 @@
by adding context parameters in the <literal>portlet.xml</literal> file or
portlet init-parameters. The possibilities are listed below.</para>
<table frame="all" id="portlet-dpp-init-params">
<table frame="all" xml:id="portlet-dpp-init-params">
<title><classname>DispatcherPortlet</classname> initialization parameters</title>
<tgroup cols="2">
<colspec colname="c1" colwidth="1*" align="left" />
@@ -340,7 +344,7 @@
</table>
</section>
<section id="portlet-viewservlet">
<section xml:id="portlet-viewservlet">
<title>The <classname>ViewRendererServlet</classname></title>
<para>The rendering process in Portlet MVC is a bit more complex than in
@@ -405,7 +409,7 @@
</section>
<section id="portlet-controller">
<section xml:id="portlet-controller">
<title>Controllers</title>
<para>The controllers in Portlet MVC are very similar to the Web MVC
@@ -447,7 +451,7 @@
action request, handling a render request, and returning a model and a
view.</para>
<section id="portlet-controller-abstractcontroller">
<section xml:id="portlet-controller-abstractcontroller">
<title><classname>AbstractController</classname> and <classname>PortletContentGenerator</classname></title>
<para>Of course, just a <interfacename>Controller</interfacename>
@@ -458,7 +462,7 @@
<interfacename>ApplicationContext</interfacename> and control over
caching.</para>
<table frame="all" id="portlet-ac-features">
<table frame="all" xml:id="portlet-ac-features">
<title>Features offered by the <classname>AbstractController</classname></title>
<tgroup cols="2">
<colspec colname="c1" colwidth="1*" align="left" />
@@ -566,7 +570,7 @@ public class SampleController extends AbstractController {
controller working.</para>
</section>
<section id="portlet-controller-simple">
<section xml:id="portlet-controller-simple">
<title>Other simple controllers</title>
<para>Although you can extend <classname>AbstractController</classname>,
@@ -584,7 +588,7 @@ public class SampleController extends AbstractController {
then it uses "view" as the view name.</para>
</section>
<section id="portlet-controller-command">
<section xml:id="portlet-controller-command">
<title>Command Controllers</title>
<para>Spring Portlet MVC has the exact same hierarchy of
@@ -646,7 +650,7 @@ public class SampleController extends AbstractController {
start using them.</para>
</section>
<section id="portlet-controller-wrapping">
<section xml:id="portlet-controller-wrapping">
<title><classname>PortletWrappingController</classname></title>
<para>Instead of developing new controllers, it is possible to use
@@ -673,7 +677,7 @@ public class SampleController extends AbstractController {
</section>
</section>
<section id="portlet-handlermapping">
<section xml:id="portlet-handlermapping">
<title>Handler mappings</title>
<para>Using a handler mapping you can map incoming portlet requests to
@@ -747,7 +751,7 @@ public class SampleController extends AbstractController {
Handlers.</para></listitem>
</itemizedlist>
<section id="portlet-handlermapping-portletmode">
<section xml:id="portlet-handlermapping-portletmode">
<title><classname>PortletModeHandlerMapping</classname></title>
<para>This is a simple handler mapping that maps incoming requests
@@ -765,7 +769,7 @@ public class SampleController extends AbstractController {
</bean>]]></programlisting>
</section>
<section id="portlet-handlermapping-parameter">
<section xml:id="portlet-handlermapping-parameter">
<title><classname>ParameterHandlerMapping</classname></title>
<para>If we need to navigate around to multiple controllers without
@@ -791,7 +795,7 @@ public class SampleController extends AbstractController {
</bean>]]></programlisting>
</section>
<section id="portlet-handlermapping-portletmodeparameter">
<section xml:id="portlet-handlermapping-portletmodeparameter">
<title><classname>PortletModeParameterHandlerMapping</classname></title>
<para>The most powerful built-in handler mapping,
@@ -838,7 +842,7 @@ public class SampleController extends AbstractController {
defaults for each mode and an overall default as well.</para>
</section>
<section id="portlet-handlermapping-interceptor">
<section xml:id="portlet-handlermapping-interceptor">
<title>Adding <interfacename>HandlerInterceptor</interfacename>s</title>
<para>Spring's handler mapping mechanism has a notion of handler
@@ -879,7 +883,7 @@ public class SampleController extends AbstractController {
to check what kind of request it is before processing it.</para>
</section>
<section id="portlet-handlermapping-interceptoradapter">
<section xml:id="portlet-handlermapping-interceptoradapter">
<title><classname>HandlerInterceptorAdapter</classname></title>
<para>As with the servlet package, the portlet package has a
@@ -892,7 +896,7 @@ public class SampleController extends AbstractController {
</section>
<section id="portlet-handlermapping-parameterinterceptor">
<section xml:id="portlet-handlermapping-parameterinterceptor">
<title><classname>ParameterMappingInterceptor</classname></title>
<para>The portlet package also has a concrete interceptor named
@@ -920,7 +924,7 @@ public class SampleController extends AbstractController {
</section>
</section>
<section id="portlet-viewresolver">
<section xml:id="portlet-viewresolver">
<title>Views and resolving them</title>
<para>As mentioned previously, Spring Portlet MVC directly reuses all
@@ -960,7 +964,7 @@ public class SampleController extends AbstractController {
that they work in servlet views.</para>
</section>
<section id="portlet-multipart">
<section xml:id="portlet-multipart">
<title>Multipart (file upload) support</title>
<para>Spring Portlet MVC has built-in multipart support to handle file
@@ -970,7 +974,7 @@ public class SampleController extends AbstractController {
in the <literal>org.springframework.web.portlet.multipart</literal>
package. Spring provides a <interfacename>PortletMultipartResolver</interfacename>
for use with
<ulink url="http://jakarta.apache.org/commons/fileupload">Commons FileUpload</ulink>.
<link xl:href="http://jakarta.apache.org/commons/fileupload">Commons FileUpload</link>.
How uploading files is supported will be described in the rest of this section.</para>
<para>By default, no multipart handling will be done by Spring Portlet
@@ -995,7 +999,7 @@ public class SampleController extends AbstractController {
consequently no multipart support will be in effect.</para>
</note>
<section id="portlet-multipart-resolver">
<section xml:id="portlet-multipart-resolver">
<title>Using the <interfacename>PortletMultipartResolver</interfacename></title>
<para>The following example shows how to use the
@@ -1033,7 +1037,7 @@ public class SampleController extends AbstractController {
<interfacename>RenderRequest</interfacename>.</para>
</section>
<section id="portlet-multipart-forms">
<section xml:id="portlet-multipart-forms">
<title>Handling a file upload in a form</title>
<para>After the
@@ -1230,7 +1234,7 @@ public class FileUploadBean {
</section>
</section>
<section id="portlet-exceptionresolver">
<section xml:id="portlet-exceptionresolver">
<title>Handling exceptions</title>
<para>Just like Servlet MVC, Portlet MVC provides
@@ -1243,7 +1247,7 @@ public class FileUploadBean {
to a view name.</para>
</section>
<section id="portlet-annotation">
<section xml:id="portlet-annotation">
<title>Annotation-based controller configuration</title>
<para>Spring 2.5 introduced an annotation-based programming model for MVC
@@ -1257,12 +1261,12 @@ public class FileUploadBean {
direct dependencies on Servlet or Portlet API's, although they can easily
get access to Servlet or Portlet facilities if desired.</para>
<!--
PetPortal is no longer included with the Spring distribution as of
Spring 3.0.0.RC1. Thus, the following is commented out until further
notice.
-->
<!--
<!--
PetPortal is no longer included with the Spring distribution as of
Spring 3.0.0.RC1. Thus, the following is commented out until further
notice.
-->
<!--
<tip>
<para>The Spring distribution ships with the
<emphasis>PetPortal</emphasis> sample, which is a portal application that takes
@@ -1270,12 +1274,12 @@ public class FileUploadBean {
of simple form processing. You can find the <emphasis>PetPortal</emphasis>
application in the <literal>'samples/petportal'</literal> directory.</para>
</tip>
-->
-->
<para>The following sections document these annotations and how they are
most commonly used in a Portlet environment.</para>
<section id="portlet-ann-setup">
<section xml:id="portlet-ann-setup">
<title>Setting up the dispatcher for annotation support</title>
<para><emphasis><interfacename>@RequestMapping</interfacename> will only be processed
@@ -1311,7 +1315,7 @@ public class FileUploadBean {
specifying a custom <interfacename>WebBindingInitializer</interfacename> (see below).</para>
</section>
<section id="portlet-ann-controller">
<section xml:id="portlet-ann-controller">
<title>Defining a controller with
<interfacename>@Controller</interfacename></title>
@@ -1358,7 +1362,7 @@ public class FileUploadBean {
</programlisting>
</section>
<section id="portlet-ann-requestmapping">
<section xml:id="portlet-ann-requestmapping">
<title>Mapping requests with
<interfacename>@RequestMapping</interfacename></title>
@@ -1439,7 +1443,7 @@ public class PetSitesEditController {
}</programlisting>
</section>
<section id="portlet-ann-requestmapping-arguments">
<section xml:id="portlet-ann-requestmapping-arguments">
<title>Supported handler method arguments</title>
<para>Handler methods which are annotated with
@@ -1587,7 +1591,7 @@ public class PetSitesEditController {
</itemizedlist></para>
</section>
<section id="portlet-ann-requestparam">
<section xml:id="portlet-ann-requestparam">
<title>Binding request parameters to method parameters with
<classname>@RequestParam</classname></title>
@@ -1620,7 +1624,7 @@ public class PetSitesEditController {
<literal>@RequestParam(value="id", required=false)</literal>).</para>
</section>
<section id="portlet-ann-modelattrib">
<section xml:id="portlet-ann-modelattrib">
<title>Providing a link to data from the model with
<classname>@ModelAttribute</classname></title>
@@ -1680,7 +1684,7 @@ public class PetSitesEditController {
}</programlisting>
</section>
<section id="portlet-ann-sessionattrib">
<section xml:id="portlet-ann-sessionattrib">
<title>Specifying attributes to store in a Session with
<classname>@SessionAttributes</classname></title>
@@ -1703,7 +1707,7 @@ public class PetSitesEditController {
</programlisting>
</section>
<section id="portlet-ann-webdatabinder">
<section xml:id="portlet-ann-webdatabinder">
<title>Customizing <classname>WebDataBinder</classname>
initialization</title>
@@ -1713,7 +1717,7 @@ public class PetSitesEditController {
controller or externalize your configuration by providing a custom
<interfacename>WebBindingInitializer</interfacename>.</para>
<section id="portlet-ann-initbinder">
<section xml:id="portlet-ann-initbinder">
<title>Customizing data binding with
<interfacename>@InitBinder</interfacename></title>
@@ -1754,7 +1758,7 @@ public class MyFormController {
}</programlisting>
</section>
<section id="portlet-ann-webbindinginitializer">
<section xml:id="portlet-ann-webbindinginitializer">
<title>Configuring a custom
<interfacename>WebBindingInitializer</interfacename></title>
@@ -1768,7 +1772,7 @@ public class MyFormController {
</section>
</section>
<section id="portlet-deployment">
<section xml:id="portlet-deployment">
<title>Portlet application deployment</title>
<para>The process of deploying a Spring Portlet MVC application is no

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<preface xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<preface xml:id="preface"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="preface">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Preface</title>
<para>Developing software applications is hard enough even with good tools
@@ -33,6 +37,6 @@
<para>This document provides a reference guide to Spring's features. If you
have any requests or comments, please add an issue at
<ulink url="http://jira.springsource.org/SPR" />.
<link xl:href="http://jira.springsource.org/SPR" />.
</para>
</preface>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="remoting"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="remoting">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Remoting and web services using Spring</title>
<section id="remoting-introduction">
<section xml:id="remoting-introduction">
<title>Introduction</title>
<para>Spring features integration classes for remoting support using
@@ -102,7 +106,7 @@ public class AccountServiceImpl implements AccountService {
public void insertAccount(Account acc) {
<lineannotation>// do something...</lineannotation>
}
public List&lt;Account&gt; getAccounts(String name) {
<lineannotation>// do something...</lineannotation>
}
@@ -113,7 +117,7 @@ public class AccountServiceImpl implements AccountService {
show an example using Hessian as the protocol.</para>
</section>
<section id="remoting-rmi">
<section xml:id="remoting-rmi">
<title>Exposing services using RMI</title>
<para>Using Spring's support for RMI, you can transparently expose your
@@ -125,7 +129,7 @@ public class AccountServiceImpl implements AccountService {
example plug in security frameworks or custom security credentials
here.</para>
<section id="remoting-rmi-server">
<section xml:id="remoting-rmi-server">
<title>Exporting the service using the
<classname>RmiServiceExporter</classname></title>
@@ -151,7 +155,7 @@ public class AccountServiceImpl implements AccountService {
&lt;property name="serviceName" value="AccountService"/&gt;
&lt;property name="service" ref="accountService"/&gt;
&lt;property name="serviceInterface" value="example.AccountService"/&gt;
<lineannotation>&lt;!-- defaults to <literal>1099</literal> --&gt;</lineannotation>
<lineannotation>&lt;!-- defaults to 1099 --&gt;</lineannotation>
&lt;property name="registryPort" value="1199"/&gt;
&lt;/bean&gt;</programlisting>
@@ -169,7 +173,7 @@ public class AccountServiceImpl implements AccountService {
</note>
</section>
<section id="remoting-rmi-client">
<section xml:id="remoting-rmi-client">
<title>Linking in the service at the client</title>
<para>Our client is a simple object using the
@@ -208,14 +212,14 @@ public class AccountServiceImpl implements AccountService {
</section>
</section>
<section id="remoting-caucho-protocols">
<section xml:id="remoting-caucho-protocols">
<title>Using Hessian or Burlap to remotely call services via HTTP</title>
<para>Hessian offers a binary HTTP-based remoting protocol. It is
developed by Caucho and more information about Hessian itself can be found
at <ulink url="http://www.caucho.com"></ulink>.</para>
at <link xl:href="http://www.caucho.com"></link>.</para>
<section id="remoting-caucho-protocols-hessian">
<section xml:id="remoting-caucho-protocols-hessian">
<title>Wiring up the <classname>DispatcherServlet</classname> for
Hessian and co.</title>
@@ -254,7 +258,7 @@ public class AccountServiceImpl implements AccountService {
this case.</para>
</section>
<section id="remoting-caucho-protocols-hessian-server">
<section xml:id="remoting-caucho-protocols-hessian-server">
<title>Exposing your beans by using the
<classname>HessianServiceExporter</classname></title>
@@ -307,7 +311,7 @@ public class AccountServiceImpl implements AccountService {
&lt;/servlet-mapping&gt;</programlisting>
</section>
<section id="remoting-caucho-protocols-hessian-client">
<section xml:id="remoting-caucho-protocols-hessian-client">
<title>Linking in the service on the client</title>
<para>Using the <classname>HessianProxyFactoryBean</classname> we can
@@ -327,7 +331,7 @@ public class AccountServiceImpl implements AccountService {
&lt;/bean&gt;</programlisting>
</section>
<section id="remoting-caucho-protocols-burlap">
<section xml:id="remoting-caucho-protocols-burlap">
<title>Using Burlap</title>
<para>We won't discuss Burlap, the XML-based equivalent of Hessian, in
@@ -337,7 +341,7 @@ public class AccountServiceImpl implements AccountService {
set to go.</para>
</section>
<section id="remoting-caucho-protocols-security">
<section xml:id="remoting-caucho-protocols-security">
<title>Applying HTTP basic authentication to a service exposed through
Hessian or Burlap</title>
@@ -354,7 +358,7 @@ public class AccountServiceImpl implements AccountService {
&lt;property name="interceptors" ref="authorizationInterceptor"/&gt;
&lt;/bean&gt;
&lt;bean id="authorizationInterceptor"
&lt;bean id="authorizationInterceptor"
class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor"&gt;
&lt;property name="authorizedRoles" value="administrator,operator"/&gt;
&lt;/bean&gt;</programlisting>
@@ -367,13 +371,13 @@ public class AccountServiceImpl implements AccountService {
<note>
<para>Of course, this example doesn't show a flexible kind of security
infrastructure. For more options as far as security is concerned, have
a look at the Spring Security project at <ulink
url="http://static.springsource.org/spring-security/site/"></ulink>.</para>
a look at the Spring Security project at <link
xl:href="http://static.springsource.org/spring-security/site/"></link>.</para>
</note>
</section>
</section>
<section id="remoting-httpinvoker">
<section xml:id="remoting-httpinvoker">
<title>Exposing services using HTTP invokers</title>
<para>As opposed to Burlap and Hessian, which are both lightweight
@@ -387,11 +391,11 @@ public class AccountServiceImpl implements AccountService {
<para>Under the hood, Spring uses either the standard facilities provided
by J2SE to perform HTTP calls or Commons
<classname>HttpClient</classname>. Use the latter if you need more
advanced and easy-to-use functionality. Refer to <ulink
url="http://jakarta.apache.org/commons/httpclient">jakarta.apache.org/commons/httpclient</ulink>
advanced and easy-to-use functionality. Refer to <link
xl:href="http://jakarta.apache.org/commons/httpclient">jakarta.apache.org/commons/httpclient</link>
for more info.</para>
<section id="remoting-httpinvoker-server">
<section xml:id="remoting-httpinvoker-server">
<title>Exposing the service object</title>
<para>Setting up the HTTP invoker infrastructure for a service object
@@ -445,13 +449,13 @@ public class AccountServiceImpl implements AccountService {
You can configure the <classname>SimpleHttpServerFactoryBean</classname> together with a
<classname>SimpleHttpInvokerServiceExporter</classname> as is shown in this example:</para>
<programlisting language="xml">&lt;bean name="accountExporter"
<programlisting language="xml">&lt;bean name="accountExporter"
class="org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter"&gt;
&lt;property name="service" ref="accountService"/&gt;
&lt;property name="serviceInterface" value="example.AccountService"/&gt;
&lt;/bean&gt;
&lt;bean id="httpServer"
&lt;bean id="httpServer"
class="org.springframework.remoting.support.SimpleHttpServerFactoryBean"&gt;
&lt;property name="contexts"&gt;
&lt;util:map&gt;
@@ -463,7 +467,7 @@ public class AccountServiceImpl implements AccountService {
</programlisting>
</section>
<section id="remoting-httpinvoker-client">
<section xml:id="remoting-httpinvoker-client">
<title>Linking in the service at the client</title>
<para>Again, linking in the service from the client much resembles the
@@ -490,7 +494,7 @@ public class AccountServiceImpl implements AccountService {
</section>
</section>
<section id="remoting-web-services">
<section xml:id="remoting-web-services">
<title>Web services</title>
<para>Spring provides full support for standard Java web services
@@ -533,13 +537,13 @@ public class AccountServiceImpl implements AccountService {
</note>
<para>In addition to stock support for JAX-RPC and JAX-WS in Spring Core,
the Spring portfolio also features <ulink
url="http://www.springframework.org/spring-ws">Spring Web
Services</ulink>, a solution for contract-first, document-driven web
the Spring portfolio also features <link
xl:href="http://www.springframework.org/spring-ws">Spring Web
Services</link>, a solution for contract-first, document-driven web
services - highly recommended for building modern, future-proof web
services.</para>
<section id="remoting-web-services-jaxrpc-export">
<section xml:id="remoting-web-services-jaxrpc-export">
<title>Exposing servlet-based web services using JAX-RPC</title>
<para>Spring provides a convenience base class for JAX-RPC servlet
@@ -566,7 +570,7 @@ public class AccountServiceImpl implements AccountService {
*/</lineannotation>import org.springframework.remoting.jaxrpc.ServletEndpointSupport;
public class AccountServiceEndpoint extends ServletEndpointSupport implements RemoteAccountService {
private AccountService biz;
protected void onInit() {
@@ -576,7 +580,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
public void insertAccount(Account acc) throws RemoteException {
biz.insertAccount(acc);
}
public Account[] getAccounts(String name) throws RemoteException {
return biz.getAccounts(name);
}
@@ -593,7 +597,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
using Axis.</para>
</section>
<section id="remoting-web-services-jaxrpc-access">
<section xml:id="remoting-web-services-jaxrpc-access">
<title>Accessing web services using JAX-RPC</title>
<para>Spring provides two factory beans to create JAX-RPC web service
@@ -641,11 +645,11 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
<programlisting language="java">public class AccountClientImpl {
private RemoteAccountService service;
public void setService(RemoteAccountService service) {
this.service = service;
}
public void foo() {
try {
service.insertAccount(...);
@@ -677,11 +681,11 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
<programlisting language="java">public class AccountClientImpl {
private AccountService service;
public void setService(AccountService service) {
this.service = service;
}
public void foo() {
service.insertAccount(...);
}
@@ -699,7 +703,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
on the runtime implications.</para>
</section>
<section id="remoting-web-services-jaxrpc-mapping-registration">
<section xml:id="remoting-web-services-jaxrpc-mapping-registration">
<title>Registering JAX-RPC Bean Mappings</title>
<para>To transfer complex objects over the wire such as
@@ -733,7 +737,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
}</programlisting>
</section>
<section id="remoting-web-services-jaxrpc-handler-registration">
<section xml:id="remoting-web-services-jaxrpc-handler-registration">
<title>Registering your own JAX-RPC Handler</title>
<para>In this section we will register our own
@@ -793,7 +797,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
&lt;/bean&gt;</programlisting>
</section>
<section id="remoting-web-services-jaxws-export-servlet">
<section xml:id="remoting-web-services-jaxws-export-servlet">
<title>Exposing servlet-based web services using JAX-WS</title>
<para>Spring provides a convenient base class for JAX-WS servlet
@@ -849,7 +853,7 @@ public class AccountServiceEndpoint extends SpringBeanAutowiringSupport {
deployment. See Java EE 5 web service tutorials for details.</para>
</section>
<section id="remoting-web-services-jaxws-export-standalone">
<section xml:id="remoting-web-services-jaxws-export-standalone">
<title>Exporting standalone web services using JAX-WS</title>
<para>The built-in JAX-WS provider that comes with Sun's JDK 1.6
@@ -903,7 +907,7 @@ public class AccountServiceEndpoint {
}</programlisting>
</section>
<section id="remoting-web-services-jaxws-export-ri">
<section xml:id="remoting-web-services-jaxws-export-ri">
<title>Exporting web services using the JAX-WS RI's Spring
support</title>
@@ -925,12 +929,12 @@ public class AccountServiceEndpoint {
beans (through the use of <literal>@Autowired</literal>, as shown
above).</para>
<para>Check out <ulink
url="https://jax-ws-commons.dev.java.net/spring/">https://jax-ws-commons.dev.java.net/spring/</ulink>
<para>Check out <link
xl:href="https://jax-ws-commons.dev.java.net/spring/">https://jax-ws-commons.dev.java.net/spring/</link>
for the details on setup and usage style.</para>
</section>
<section id="remoting-web-services-jaxws-access">
<section xml:id="remoting-web-services-jaxws-access">
<title>Accessing web services using JAX-WS</title>
<para>Analogous to the JAX-RPC support, Spring provides two factory
@@ -995,7 +999,7 @@ public class AccountServiceEndpoint {
</section>
</section>
<section id="remoting-jms">
<section xml:id="remoting-jms">
<title>JMS</title>
<para>It is also possible to expose services transparently using JMS as
@@ -1050,7 +1054,7 @@ public class SimpleCheckingAccountService implements CheckingAccountService {
&lt;/beans&gt;</programlisting>
<section id="remoting-jms-server">
<section xml:id="remoting-jms-server">
<title>Server-side configuration</title>
<para>On the server, you just need to expose the service object using
@@ -1091,7 +1095,7 @@ public class Server {
}</programlisting>
</section>
<section id="remoting-jms-client">
<section xml:id="remoting-jms-client">
<title>Client-side configuration</title>
<para>The client merely needs to create a client-side proxy that will
@@ -1130,18 +1134,18 @@ public class Client {
service.cancelAccount(new Long(10));
}
}</programlisting>
</section>
<para>You may also wish to investigate the support provided by the <ulink
url="http://lingo.codehaus.org/">Lingo</ulink> project, which (to quote
<para>You may also wish to investigate the support provided by the <link
xl:href="http://lingo.codehaus.org/">Lingo</link> project, which (to quote
the homepage blurb) <quote>
<emphasis>... is a lightweight POJO based remoting and messaging
library based on the Spring Framework's remoting libraries which
extends it to support JMS.</emphasis>
</quote></para>
</section>
</section>
<section id="remoting-autodection-remote-interfaces">
<section xml:id="remoting-autodection-remote-interfaces">
<title>Auto-detection is not implemented for remote interfaces</title>
<para>The main reason why auto-detection of implemented interfaces does
@@ -1166,7 +1170,7 @@ public class Client {
controlled exposure of specific methods.</para>
</section>
<section id="remoting-considerations">
<section xml:id="remoting-considerations">
<title>Considerations when choosing a technology</title>
<para>Each and every technology presented here has its drawbacks. You
@@ -1209,7 +1213,7 @@ public class Client {
in third-party or custom solutions here.</para>
</section>
<section id="rest-client-access">
<section xml:id="rest-client-access">
<title>Accessing RESTful services on the Client</title>
<para>The <classname>RestTemplate</classname> is the core class for
@@ -1232,7 +1236,7 @@ public class Client {
<classname>RestTemplate</classname> and its associated
<interfacename>HttpMessageConverters</interfacename>.</para>
<section id="rest-resttemplate">
<section xml:id="rest-resttemplate">
<title>RestTemplate</title>
<para>Invoking RESTful services in Java is typically done using a helper
@@ -1274,63 +1278,63 @@ if (HttpStatus.SC_CREATED == post.getStatusCode()) {
<row>
<entry>DELETE</entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#delete(String,%20Object...)">delete</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#delete(String,%20Object...)">delete</link></entry>
</row>
<row>
<entry>GET</entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#getForObject(String,%20Class,%20Object...)">getForObject</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#getForObject(String,%20Class,%20Object...)">getForObject</link></entry>
</row>
<row>
<entry></entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#getForEntity(String,%20Class,%20Object...)">getForEntity</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#getForEntity(String,%20Class,%20Object...)">getForEntity</link></entry>
</row>
<row>
<entry>HEAD</entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#headForHeaders(String,%20Object...)">headForHeaders(String
url, String… urlVariables)</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#headForHeaders(String,%20Object...)">headForHeaders(String
url, String… urlVariables)</link></entry>
</row>
<row>
<entry>OPTIONS</entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#optionsForAllow(String,%20Object...)">optionsForAllow(String
url, String… urlVariables)</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#optionsForAllow(String,%20Object...)">optionsForAllow(String
url, String… urlVariables)</link></entry>
</row>
<row>
<entry>POST</entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#postForLocation(String,%20Object,%20Object...)">postForLocation(String
url, Object request, String… urlVariables)</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#postForLocation(String,%20Object,%20Object...)">postForLocation(String
url, Object request, String… urlVariables)</link></entry>
</row>
<row>
<entry></entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#postForObject(java.lang.String,%20java.lang.Object,%20java.lang.Class,%20java.lang.String...)">postForObject(String
url, Object request, Class&lt;T&gt; responseType, String…
uriVariables)</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#postForObject(java.lang.String,%20java.lang.Object,%20java.lang.Class,%20java.lang.String...)">postForObject(String
url, Object request, Class&lt;T&gt; responseType, String…
uriVariables)</link></entry>
</row>
<row>
<entry>PUT</entry>
<entry><ulink
url="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#put(String,%20Object,%20Object...)">put(String
url, Object request, String…urlVariables)</ulink></entry>
<entry><link
xl:href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/client/RestTemplate.html#put(String,%20Object,%20Object...)">put(String
url, Object request, String…urlVariables)</link></entry>
</row>
</tbody>
</tgroup>
@@ -1347,7 +1351,7 @@ if (HttpStatus.SC_CREATED == post.getStatusCode()) {
found. In case of an exception processing the HTTP request, an exception
of the type <classname>RestClientException</classname> will be
thrown; this behavior can be changed by plugging in another <interfacename>ResponseErrorHandler</interfacename>
implementation into the <classname>RestTemplate</classname>.</para>
implementation into the <classname>RestTemplate</classname>.</para>
<para>Objects passed to and returned from these methods are converted to
and from HTTP messages by
@@ -1362,7 +1366,7 @@ if (HttpStatus.SC_CREATED == post.getStatusCode()) {
<classname>SourceHttpMessageConverter</classname>. You can override
these defaults using the <methodname>messageConverters()</methodname> bean
property as would be required if using the
<classname>MarshallingHttpMessageConverter</classname> or
<classname>MarshallingHttpMessageConverter</classname> or
<classname>MappingJackson2HttpMessageConverter</classname>.</para>
<para>Each method takes URI template arguments in two forms, either as a
@@ -1435,57 +1439,57 @@ URI location = template.postForLocation(uri, booking, "1");
information on using the execute method and the meaning of its other
method arguments.</para>
<section id="rest-resttemplate-uri">
<section xml:id="rest-resttemplate-uri">
<title>Working with the URI</title>
<para>For each of the main HTTP methods, the <classname>RestTemplate</classname>
provides variants that either take a String URI or <classname>java.net.URI</classname>
as the first argument.
</para>
<para>The String URI variants accept template arguments as a
String variable length argument or as a <classname>Map&lt;String,String&gt;</classname>.
They also assume the URL String is not encoded and needs to be encoded.
For example the following:
They also assume the URL String is not encoded and needs to be encoded.
For example the following:
</para>
<programlisting language="java">restTemplate.getForObject("http://example.com/hotel list", String.class);</programlisting>
<para>will perform a GET on <filename>http://example.com/hotel%20list</filename>.
That means if the input URL String is already encoded, it will be encoded twice --
i.e. <filename>http://example.com/hotel%20list</filename> will become
<filename>http://example.com/hotel%2520list</filename>.
If this is not the intended effect, use the
That means if the input URL String is already encoded, it will be encoded twice --
i.e. <filename>http://example.com/hotel%20list</filename> will become
<filename>http://example.com/hotel%2520list</filename>.
If this is not the intended effect, use the
<classname>java.net.URI</classname> method variant, which assumes
the URL is already encoded is also generally useful if you want
to reuse a single (fully expanded) <classname>URI</classname>
multiple times.</para>
<para>The <classname>UriComponentsBuilder</classname> class can be used
to build and encode the <classname>URI</classname> including support
to build and encode the <classname>URI</classname> including support
for URI templates. For example you can start with a URL String:
</para>
<programlisting language="java">UriComponents uriComponents =
<programlisting language="java">UriComponents uriComponents =
UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build()
.expand("42", "21")
.encode();
URI uri = uriComponents.toUri();</programlisting>
<para>Or specify each URI component individually:</para>
<programlisting language="java">UriComponents uriComponents =
<programlisting language="java">UriComponents uriComponents =
UriComponentsBuilder.newInstance()
.scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build()
.expand("42", "21")
.encode();
URI uri = uriComponents.toUri();</programlisting>
</section>
<section id="rest-template-headers">
<section xml:id="rest-template-headers">
<title>Dealing with request and response headers</title>
<para>Besides the methods described above, the <classname>RestTemplate</classname>
@@ -1493,7 +1497,7 @@ URI uri = uriComponents.toUri();</programlisting>
used for arbitrary HTTP method execution based on the <classname>HttpEntity</classname>
class.</para>
<para>Perhaps most importantly, the <methodname>exchange()</methodname>
<para>Perhaps most importantly, the <methodname>exchange()</methodname>
method can be used to add request headers and read response headers.
For example:</para>
@@ -1513,7 +1517,7 @@ String body = response.getBody();</programlisting>
</section>
</section>
<section id="rest-message-conversion">
<section xml:id="rest-message-conversion">
<title>HTTP Message Conversion</title>
<para>Objects passed to and returned from the methods
@@ -1557,7 +1561,7 @@ String body = response.getBody();</programlisting>
can be overridden by setting the
<classname>supportedMediaTypes</classname> bean property</para>
<section id="rest-string-converter">
<section xml:id="rest-string-converter">
<title>StringHttpMessageConverter</title>
<para>An <interfacename>HttpMessageConverter</interfacename>
@@ -1568,7 +1572,7 @@ String body = response.getBody();</programlisting>
<literal>text/plain</literal>.</para>
</section>
<section id="rest-form-converter">
<section xml:id="rest-form-converter">
<title>FormHttpMessageConverter</title>
<para>An <interfacename>HttpMessageConverter</interfacename>
@@ -1579,7 +1583,7 @@ String body = response.getBody();</programlisting>
String&gt;</literal>.</para>
</section>
<section id="rest-byte-converter">
<section xml:id="rest-byte-converter">
<title>ByteArrayHttpMessageConverter</title>
<para>An <interfacename>HttpMessageConverter</interfacename>
@@ -1592,7 +1596,7 @@ String body = response.getBody();</programlisting>
overriding <literal>getContentType(byte[])</literal>.</para>
</section>
<section id="rest-marhsalling-converter">
<section xml:id="rest-marhsalling-converter">
<title>MarshallingHttpMessageConverter</title>
<para>An <interfacename>HttpMessageConverter</interfacename>
@@ -1606,22 +1610,22 @@ String body = response.getBody();</programlisting>
this converter supports (<literal>text/xml</literal>) and
(<literal>application/xml</literal>).</para>
</section>
<section id="rest-mapping-json-converter">
<section xml:id="rest-mapping-json-converter">
<title>MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter with Jackson 1.x)</title>
<para>An <interfacename>HttpMessageConverter</interfacename>
implementation that can read and write JSON using Jackson's
<interfacename>ObjectMapper</interfacename>. JSON mapping can be
customized as needed through the use of Jackson's provided annotations. When
further control is needed, a custom
<interfacename>ObjectMapper</interfacename> can be injected through
the <literal>ObjectMapper</literal> property for cases where custom
JSON serializers/deserializers need to be provided for specific types.
<para>An <interfacename>HttpMessageConverter</interfacename>
implementation that can read and write JSON using Jackson's
<interfacename>ObjectMapper</interfacename>. JSON mapping can be
customized as needed through the use of Jackson's provided annotations. When
further control is needed, a custom
<interfacename>ObjectMapper</interfacename> can be injected through
the <literal>ObjectMapper</literal> property for cases where custom
JSON serializers/deserializers need to be provided for specific types.
By default this converter supports (<literal>application/json</literal>).</para>
</section>
<section id="rest-source-converter">
<section xml:id="rest-source-converter">
<title>SourceHttpMessageConverter</title>
<para>An <interfacename>HttpMessageConverter</interfacename>
@@ -1634,7 +1638,7 @@ String body = response.getBody();</programlisting>
(<literal>application/xml</literal>).</para>
</section>
<section id="rest-buffered-image-converter">
<section xml:id="rest-buffered-image-converter">
<title>BufferedImageHttpMessageConverter</title>
<para>An <interfacename>HttpMessageConverter</interfacename>

View File

@@ -1,29 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="resources"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="resources">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Resources</title>
<section id="resources-introduction">
<section xml:id="resources-introduction">
<title>Introduction</title>
<para>Java's standard <classname>java.net.URL</classname> class and
standard handlers for various URL prefixes unfortunately are not quite
adequate enough for all access to low-level resources. For example,
there is no standardized <classname>URL</classname> implementation
that may be used to access a resource that needs to be obtained from
the classpath, or relative to a
<interfacename>ServletContext</interfacename>. While it is possible
there is no standardized <classname>URL</classname> implementation
that may be used to access a resource that needs to be obtained from
the classpath, or relative to a
<interfacename>ServletContext</interfacename>. While it is possible
to register new handlers for specialized <classname>URL</classname>
prefixes (similar to existing handlers for prefixes such as
<literal>http:</literal>), this is generally quite complicated, and the
<classname>URL</classname> interface still lacks some desirable
prefixes (similar to existing handlers for prefixes such as
<literal>http:</literal>), this is generally quite complicated, and the
<classname>URL</classname> interface still lacks some desirable
functionality, such as a method to check for the existence of the
resource being pointed to.</para>
resource being pointed to.</para>
</section>
<section id="resources-resource">
<section xml:id="resources-resource">
<title>The <interfacename>Resource</interfacename> interface</title>
<para>Spring's <interfacename>Resource</interfacename> interface is meant
@@ -122,14 +126,14 @@
<classname>URL</classname> to do its work.</para>
</section>
<section id="resources-implementations">
<section xml:id="resources-implementations">
<title>Built-in <interfacename>Resource</interfacename> implementations</title>
<para>There are a number of <interfacename>Resource</interfacename>
implementations that come supplied straight out of the box in
Spring:</para>
<section id="resources-implementations-urlresource">
<section xml:id="resources-implementations-urlresource">
<title><classname>UrlResource</classname></title>
<para>The <classname>UrlResource</classname> wraps a
@@ -156,7 +160,7 @@
URL string, and will create a <classname>UrlResource</classname>.</para>
</section>
<section id="resources-implementations-classpathresource">
<section xml:id="resources-implementations-classpathresource">
<title><classname>ClassPathResource</classname></title>
<para>This class represents a resource which should be obtained from the
@@ -182,7 +186,7 @@
<classname>ClassPathResource</classname> in that case.</para>
</section>
<section id="resources-implementations-filesystemresource">
<section xml:id="resources-implementations-filesystemresource">
<title><classname>FileSystemResource</classname></title>
<para>This is a <interfacename>Resource</interfacename> implementation
@@ -191,7 +195,7 @@
<classname>URL</classname>.</para>
</section>
<section id="resources-implementations-servletcontextresource">
<section xml:id="resources-implementations-servletcontextresource">
<title><classname>ServletContextResource</classname></title>
<para>This is a <interfacename>Resource</interfacename> implementation
@@ -207,7 +211,7 @@
conceivable) is actually dependent on the Servlet container.</para>
</section>
<section id="resources-implementations-inputstreamresource">
<section xml:id="resources-implementations-inputstreamresource">
<title><classname>InputStreamResource</classname></title>
<para>A <interfacename>Resource</interfacename> implementation for a
@@ -226,7 +230,7 @@
need to read a stream multiple times.</para>
</section>
<section id="resources-implementations-bytearrayresource">
<section xml:id="resources-implementations-bytearrayresource">
<title><classname>ByteArrayResource</classname></title>
<para>This is a <interfacename>Resource</interfacename> implementation
@@ -240,7 +244,7 @@
</section>
</section>
<section id="resources-resourceloader">
<section xml:id="resources-resourceloader">
<title>The <interfacename>ResourceLoader</interfacename></title>
<para>The <interfacename>ResourceLoader</interfacename> interface is meant
@@ -295,7 +299,7 @@
<classname>String</classname>s to
<interfacename>Resource</interfacename>s:</para>
<table pgwide="1" id="resources-resource-strings">
<table pgwide="1" xml:id="resources-resource-strings">
<title>Resource strings</title>
<tgroup cols="3">
@@ -357,7 +361,7 @@
</table>
</section>
<section id="resources-resourceloaderaware">
<section xml:id="resources-resourceloaderaware">
<title>The <interfacename>ResourceLoaderAware</interfacename> interface</title>
<para>The <interfacename>ResourceLoaderAware</interfacename> interface is
@@ -408,7 +412,7 @@
see <xref linkend="beans-autowired-annotation"/>.</para>
</section>
<section id="resources-as-dependencies">
<section xml:id="resources-as-dependencies">
<title><literal>Resources</literal> as dependencies</title>
<para>If the bean itself is going to determine and supply the resource
@@ -429,8 +433,8 @@
<literal>myBean</literal> has a template property of type
<interfacename>Resource</interfacename>, it can be configured with a
simple string for that resource, as follows:</para>
<programlisting language="xml"><![CDATA[<bean id="myBean" class="...">
<programlisting language="xml"><![CDATA[<bean id="myBean" class="...">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>]]></programlisting>
@@ -454,10 +458,10 @@
<programlisting language="xml"><![CDATA[<property name="template" value="file:/some/resource/path/myTemplate.txt"/>]]></programlisting>
</section>
<section id="resources-app-ctx">
<section xml:id="resources-app-ctx">
<title>Application contexts and <interfacename>Resource</interfacename> paths</title>
<section id="resources-app-ctx-construction">
<section xml:id="resources-app-ctx-construction">
<title>Constructing application contexts</title>
<para>An application context constructor (for a specific application
@@ -498,7 +502,7 @@
subsequently used as a <interfacename>ResourceLoader</interfacename>,
any unprefixed paths will still be treated as filesystem paths.</para>
<section id="resources-app-ctx-classpathxml">
<section xml:id="resources-app-ctx-classpathxml">
<title>Constructing <classname>ClassPathXmlApplicationContext</classname> instances - shortcuts</title>
<para>The <classname>ClassPathXmlApplicationContext</classname>
@@ -533,7 +537,7 @@
</section>
</section>
<section id="resources-app-ctx-wildcards-in-resource-paths">
<section xml:id="resources-app-ctx-wildcards-in-resource-paths">
<title>Wildcards in application context constructor resource paths</title>
<para>The resource paths in application context constructor values may
@@ -559,7 +563,7 @@
<interfacename>Resource</interfacename>, as a resource points to just
one resource at a time.</para>
<section id="resources-app-ctx-ant-patterns-in-paths">
<section xml:id="resources-app-ctx-ant-patterns-in-paths">
<title>Ant-style Patterns</title>
<para>When the path location contains an Ant-style pattern, for example:</para>
@@ -581,12 +585,12 @@
parses the jar URL and then traverses the contents of the jar file
to resolve the wildcards.</para>
<section id="resources-app-ctx-portability">
<section xml:id="resources-app-ctx-portability">
<title>Implications on portability</title>
<para>If the specified path is already a file URL (either
explicitly, or implicitly because the base
<interfacename>ResourceLoader</interfacename> is a
<interfacename>ResourceLoader</interfacename> is a
filesystem one, then wildcarding is guaranteed to work in a
completely portable fashion.</para>
@@ -613,7 +617,7 @@
</section>
</section>
<section id="resources-classpath-wildcards">
<section xml:id="resources-classpath-wildcards">
<title>The <literal>classpath*:</literal> prefix</title>
<para>When constructing an XML-based application context, a location
@@ -655,7 +659,7 @@
strategy described above is used for the wildcard subpath.</para>
</section>
<section id="resources-wildcards-in-path-other-stuff">
<section xml:id="resources-wildcards-in-path-other-stuff">
<title>Other notes relating to wildcards</title>
<para>Please note that "<literal>classpath*:</literal>" when
@@ -669,17 +673,17 @@
returns file system locations for a passed-in empty string (indicating
potential roots to search).</para>
<para>Ant-style patterns with "<literal>classpath:</literal>"
resources are not guaranteed to find matching resources if the root
package to search is available in multiple class path locations. This
is because a resource such as</para>
<para>Ant-style patterns with "<literal>classpath:</literal>"
resources are not guaranteed to find matching resources if the root
package to search is available in multiple class path locations. This
is because a resource such as</para>
<programlisting><![CDATA[ com/mycompany/package1/service-context.xml]]></programlisting>
<para>may be in only one location, but when a path such as</para>
<programlisting><![CDATA[ classpath:com/mycompany/**/service-context.xml]]></programlisting>
<para>is used to try to resolve it, the resolver will work off the (first) URL
returned by <methodname>getResource("com/mycompany")</methodname>;. If
this base package node exists in multiple classloader locations, the
@@ -690,7 +694,7 @@
</section>
</section>
<section id="resources-filesystemresource-caveats">
<section xml:id="resources-filesystemresource-caveats">
<title><classname>FileSystemResource</classname> caveats</title>
<para>A <classname>FileSystemResource</classname> that is not attached
@@ -731,10 +735,10 @@ ctx.getResource("/some/resource/path/myTemplate.txt");]]></programlisting>
the use of a <classname>UrlResource</classname>, by using the
<literal>file:</literal> URL prefix.</para>
<programlisting language="java"><lineannotation>// actual context type doesn't matter, the <interfacename>Resource</interfacename> will always be <classname>UrlResource</classname></lineannotation><![CDATA[
<programlisting language="java"><lineannotation>// actual context type doesn't matter, the Resource will always be UrlResource</lineannotation><![CDATA[
ctx.getResource("file:/some/resource/path/myTemplate.txt");]]></programlisting>
<programlisting language="java"><lineannotation>// force this FileSystemXmlApplicationContext to load its definition via a <classname>UrlResource</classname></lineannotation><![CDATA[
<programlisting language="java"><lineannotation>// force this FileSystemXmlApplicationContext to load its definition via a UrlResource</lineannotation><![CDATA[
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:/conf/context.xml");]]></programlisting>
</section>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="scheduling"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="scheduling">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Task Execution and Scheduling</title>
<section id="scheduling-introduction">
<section xml:id="scheduling-introduction">
<title>Introduction</title>
<para>The Spring Framework provides abstractions for asynchronous
@@ -20,8 +24,8 @@
<para>Spring also features integration classes for supporting scheduling
with the <classname>Timer</classname>, part of the JDK since 1.3, and the
Quartz Scheduler (<ulink
url="http://quartz-scheduler.org"></ulink>). Both of those
Quartz Scheduler (<link
xl:href="http://quartz-scheduler.org"></link>). Both of those
schedulers are set up using a <interfacename>FactoryBean</interfacename>
with optional references to <classname>Timer</classname> or
<classname>Trigger</classname> instances, respectively. Furthermore, a
@@ -31,7 +35,7 @@
<classname>MethodInvokingFactoryBean</classname> operation).</para>
</section>
<section id="scheduling-task-executor">
<section xml:id="scheduling-task-executor">
<title>The Spring <interfacename>TaskExecutor</interfacename>
abstraction</title>
@@ -61,7 +65,7 @@
behavior, it is possible to use this abstraction for your own
needs.</para>
<section id="scheduling-task-executor-types">
<section xml:id="scheduling-task-executor-types">
<title><interfacename>TaskExecutor</interfacename> types</title>
<para>There are a number of pre-built implementations of
@@ -80,7 +84,7 @@
pooling, keep scrolling further down the page.</para>
</listitem>
<listitem id="syncTaskExecutor">
<listitem xml:id="syncTaskExecutor">
<para><classname>SyncTaskExecutor</classname></para>
<para>This implementation doesn't execute invocations
@@ -89,7 +93,7 @@
isn't necessary such as simple test cases.</para>
</listitem>
<listitem id="concurrentTaskExecutor">
<listitem xml:id="concurrentTaskExecutor">
<para><classname>ConcurrentTaskExecutor</classname></para>
<para>This implementation is a wrapper for a Java 5
@@ -104,7 +108,7 @@
alternative.</para>
</listitem>
<listitem id="simpleThreadPoolTaskExecutor">
<listitem xml:id="simpleThreadPoolTaskExecutor">
<para><classname>SimpleThreadPoolTaskExecutor</classname></para>
<para>This implementation is actually a subclass of Quartz's
@@ -114,7 +118,7 @@
components.</para>
</listitem>
<listitem id="threadPoolTaskExecutor">
<listitem xml:id="threadPoolTaskExecutor">
<para><classname>ThreadPoolTaskExecutor</classname></para>
<sidebar>
@@ -169,7 +173,7 @@
</itemizedlist>
</section>
<section id="scheduling-task-executor-usage">
<section xml:id="scheduling-task-executor-usage">
<title>Using a <interfacename>TaskExecutor</interfacename></title>
<para>Spring's <interfacename>TaskExecutor</interfacename>
@@ -230,7 +234,7 @@ public class TaskExecutorExample {
</section>
</section>
<section id="scheduling-task-scheduler">
<section xml:id="scheduling-task-scheduler">
<title>The Spring <interfacename>TaskScheduler</interfacename>
abstraction</title>
@@ -262,7 +266,7 @@ public class TaskExecutorExample {
The fixed-rate and fixed-delay methods are for simple, periodic execution,
but the method that accepts a Trigger is much more flexible.</para>
<section id="scheduling-trigger-interface">
<section xml:id="scheduling-trigger-interface">
<title>The <interfacename>Trigger</interfacename> interface</title>
<para>The <interfacename>Trigger</interfacename> interface is
@@ -301,7 +305,7 @@ public class TaskExecutorExample {
}</programlisting>
</section>
<section id="scheduling-trigger-implementations">
<section xml:id="scheduling-trigger-implementations">
<title><interfacename>Trigger</interfacename> implementations</title>
<para>Spring provides two implementations of the
@@ -330,7 +334,7 @@ public class TaskExecutorExample {
externally.</para>
</section>
<section id="scheduling-task-scheduler-implementations">
<section xml:id="scheduling-task-scheduler-implementations">
<title><interfacename>TaskScheduler</interfacename>
implementations</title>
@@ -357,14 +361,14 @@ public class TaskExecutorExample {
</section>
</section>
<section id="scheduling-annotation-support">
<section xml:id="scheduling-annotation-support">
<title>Annotation Support for Scheduling and Asynchronous
Execution</title>
<para>Spring provides annotation support for both task scheduling and
asynchronous method execution.</para>
<section id="secheduling-enable-annotation-support">
<section xml:id="secheduling-enable-annotation-support">
<title>Enable scheduling annotations</title>
@@ -403,7 +407,7 @@ public class AppConfig {
with <interfacename>@Scheduled</interfacename>.</para>
</section>
<section id="scheduling-annotation-support-scheduled">
<section xml:id="scheduling-annotation-support-scheduled">
<title>The @Scheduled Annotation</title>
<para>The @Scheduled annotation can be added to a method along with
@@ -462,7 +466,7 @@ public void doSomething() {
</note>
</section>
<section id="scheduling-annotation-support-async">
<section xml:id="scheduling-annotation-support-async">
<title>The @Async Annotation</title>
<para>The <interfacename>@Async</interfacename> annotation can be
@@ -533,7 +537,7 @@ public class SampleBeanInititalizer {
}</programlisting>
</section>
<section id="scheduling-annotation-support-qualification">
<section xml:id="scheduling-annotation-support-qualification">
<title>Executor qualification with @Async</title>
<para>By default when specifying <interfacename>@Async</interfacename> on
@@ -557,7 +561,7 @@ void doSomething(String s) {
</section>
</section>
<section id="scheduling-task-namespace">
<section xml:id="scheduling-task-namespace">
<title>The Task Namespace</title>
<para>Beginning with Spring 3.0, there is an XML namespace for configuring
@@ -565,7 +569,7 @@ void doSomething(String s) {
<interfacename>TaskScheduler</interfacename> instances. It also provides a
convenient way to configure tasks to be scheduled with a trigger.</para>
<section id="scheduling-task-namespace-scheduler">
<section xml:id="scheduling-task-namespace-scheduler">
<title>The 'scheduler' element</title>
<para>The following element will create a
@@ -581,7 +585,7 @@ void doSomething(String s) {
are no other configuration options for the scheduler.</para>
</section>
<section id="scheduling-task-namespace-executor">
<section xml:id="scheduling-task-namespace-executor">
<title>The 'executor' element</title>
<para>The following will create a
@@ -607,8 +611,8 @@ void doSomething(String s) {
has also been provided. The configuration of the thread pool should also
be considered in light of the executor's queue capacity. For the full
description of the relationship between pool size and queue capacity,
consult the documentation for <ulink
url="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html">ThreadPoolExecutor</ulink>.
consult the documentation for <link
xl:href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html">ThreadPoolExecutor</link>.
The main idea is that when a task is submitted, the executor will first
try to use a free thread if the number of active threads is currently
less than the core size. If the core size has been reached, then the
@@ -659,7 +663,7 @@ void doSomething(String s) {
rejection-policy="CALLER_RUNS"/&gt;</programlisting>
</section>
<section id="scheduling-task-namespace-scheduled-tasks">
<section xml:id="scheduling-task-namespace-scheduled-tasks">
<title>The 'scheduled-tasks' element</title>
<para>The most powerful feature of Spring's task namespace is the
@@ -699,18 +703,18 @@ void doSomething(String s) {
</section>
</section>
<section id="scheduling-quartz">
<section xml:id="scheduling-quartz">
<title>Using the Quartz Scheduler</title>
<para>Quartz uses <classname>Trigger</classname>,
<classname>Job</classname> and <classname>JobDetail</classname> objects to
realize scheduling of all kinds of jobs. For the basic concepts behind
Quartz, have a look at <ulink
url="http://quartz-scheduler.org"></ulink>. For convenience
Quartz, have a look at <link
xl:href="http://quartz-scheduler.org"></link>. For convenience
purposes, Spring offers a couple of classes that simplify the usage of
Quartz within Spring-based applications.</para>
<section id="scheduling-quartz-jobdetail">
<section xml:id="scheduling-quartz-jobdetail">
<title>Using the JobDetailBean</title>
<para><classname>JobDetail</classname> objects contain all information
@@ -744,15 +748,15 @@ void doSomething(String s) {
public class ExampleJob extends QuartzJobBean {
private int timeout;
/**
* Setter called after the ExampleJob is instantiated
* with the value from the JobDetailBean (5)
*/
*/
public void setTimeout(int timeout) {
this.timeout = timeout;
}
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
<lineannotation>// do the actual work</lineannotation>
}
@@ -768,7 +772,7 @@ public class ExampleJob extends QuartzJobBean {
<literal>exampleJob</literal>).</emphasis></para>
</section>
<section id="scheduling-quartz-method-invoking-job">
<section xml:id="scheduling-quartz-method-invoking-job">
<title>Using the
<classname>MethodInvokingJobDetailFactoryBean</classname></title>
@@ -786,9 +790,9 @@ public class ExampleJob extends QuartzJobBean {
method (see below):</para>
<programlisting language="java">public class ExampleBusinessObject {
<lineannotation>// properties and collaborators</lineannotation>
public void doIt() {
<lineannotation>// do the actual work</lineannotation>
}
@@ -827,7 +831,7 @@ public class ExampleJob extends QuartzJobBean {
</note>
</section>
<section id="scheduling-quartz-cron">
<section xml:id="scheduling-quartz-cron">
<title>Wiring up jobs using triggers and the
<classname>SchedulerFactoryBean</classname></title>
@@ -879,13 +883,13 @@ public class ExampleJob extends QuartzJobBean {
<para>More properties are available for the
<classname>SchedulerFactoryBean</classname> for you to set, such as the
calendars used by the job details, properties to customize Quartz with,
etc. Have a look at the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html">SchedulerFactoryBean
Javadoc</ulink> for more information.</para>
etc. Have a look at the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html">SchedulerFactoryBean
Javadoc</link> for more information.</para>
</section>
</section>
<section id="scheduling-jdk-timer">
<section xml:id="scheduling-jdk-timer">
<title>Using JDK Timer support</title>
<para>The other way to schedule jobs in Spring is to use JDK
@@ -893,7 +897,7 @@ public class ExampleJob extends QuartzJobBean {
the timer that invokes methods. Wiring timers is done using the
<classname>TimerFactoryBean</classname>.</para>
<section id="scheduling-jdk-timer-creating">
<section xml:id="scheduling-jdk-timer-creating">
<title>Creating custom timers</title>
<para>Using the <classname>TimerTask</classname> you can create customer
@@ -902,11 +906,11 @@ public class ExampleJob extends QuartzJobBean {
<programlisting language="java">public class CheckEmailAddresses extends TimerTask {
private List emailAddresses;
public void setEmailAddresses(List emailAddresses) {
this.emailAddresses = emailAddresses;
}
public void run() {
<lineannotation>// iterate over all email addresses and archive them</lineannotation>
}
@@ -937,7 +941,7 @@ public class ExampleJob extends QuartzJobBean {
value). </emphasis></para>
</section>
<section id="scheduling-jdk-timer-method-invoking-task">
<section xml:id="scheduling-jdk-timer-method-invoking-task">
<title>Using the
<classname>MethodInvokingTimerTaskFactoryBean</classname></title>
@@ -955,9 +959,9 @@ public class ExampleJob extends QuartzJobBean {
below):</para>
<programlisting language="java">public class BusinessObject {
<lineannotation>// properties and collaborators</lineannotation>
public void doIt() {
<lineannotation>// do the actual work</lineannotation>
}
@@ -969,7 +973,7 @@ public class ExampleJob extends QuartzJobBean {
method being executed on a fixed schedule.</para>
</section>
<section id="scheduling-jdk-timer-factory-bean">
<section xml:id="scheduling-jdk-timer-factory-bean">
<title>Wrapping up: setting up the tasks using the
<classname>TimerFactoryBean</classname></title>

View File

@@ -1,64 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<appendix xml:id="spring-form.tld"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="spring-form.tld">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>spring-form.tld</title>
<section id="spring-form.tld-intro">
<section xml:id="spring-form.tld-intro">
<title>Introduction</title>
<para>One of the view technologies you can use with the Spring Framework
is Java Server Pages (JSPs). To help you implement views using Java Server Pages
the Spring Framework provides you with some tags for evaluating errors, setting
themes and outputting internationalized messages.</para>
<para>Please note that the various tags generated by this form tag library
are compliant with the <link xl:href="http://www.w3.org/TR/xhtml1/">XHTML-1.0-Strict specification</link> and attendant <link xl:href="http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict">DTD</link>.</para>
<para>This appendix describes the <literal>spring-form.tld</literal> tag library.</para>
<itemizedlist>
<listitem>
<xref linkend="spring-form.tld.checkbox"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.checkboxes"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.errors"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.form"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.hidden"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.input"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.label"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.option"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.options"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.password"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.radiobutton"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.radiobuttons"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.select"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.textarea"/>
</listitem>
</itemizedlist>
</section>
<para>One of the view technologies you can use with the Spring Framework
is Java Server Pages (JSPs). To help you implement views using Java Server Pages
the Spring Framework provides you with some tags for evaluating errors, setting
themes and outputting internationalized messages.</para>
<para>Please note that the various tags generated by this form tag library
are compliant with the <ulink url="http://www.w3.org/TR/xhtml1/">XHTML-1.0-Strict specification</ulink> and attendant <ulink url="http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict">DTD</ulink>.</para>
<para>This appendix describes the <literal>spring-form.tld</literal> tag library.</para>
<itemizedlist>
<listitem>
<xref linkend="spring-form.tld.checkbox"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.checkboxes"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.errors"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.form"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.hidden"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.input"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.label"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.option"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.options"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.password"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.radiobutton"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.radiobuttons"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.select"/>
</listitem>
<listitem>
<xref linkend="spring-form.tld.textarea"/>
</listitem>
</itemizedlist>
<section id="spring-form.tld.checkbox">
<section xml:id="spring-form.tld.checkbox">
<title>The <literal>checkbox</literal> tag</title>
<para>Renders an HTML 'input' tag with type 'checkbox'.</para>
<table id="spring-form.tld.checkbox.table">
@@ -459,10 +463,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.checkboxes">
<section xml:id="spring-form.tld.checkboxes">
<title>The <literal>checkboxes</literal> tag</title>
<para>Renders multiple HTML 'input' tags with type 'checkbox'.</para>
<table id="spring-form.tld.checkboxes.table">
<table xml:id="spring-form.tld.checkboxes.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -902,10 +906,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.errors">
<section xml:id="spring-form.tld.errors">
<title>The <literal>errors</literal> tag</title>
<para>Renders field errors in an HTML 'span' tag.</para>
<table id="spring-form.tld.errors.table">
<table xml:id="spring-form.tld.errors.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -1219,10 +1223,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.form">
<section xml:id="spring-form.tld.form">
<title>The <literal>form</literal> tag</title>
<para>Renders an HTML 'form' tag and exposes a binding path to inner tags for binding.</para>
<table id="spring-form.tld.form.table">
<table xml:id="spring-form.tld.form.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -1278,7 +1282,7 @@
</entry>
<entry>
<para>Name of the model attribute under which the form object is exposed.
Defaults to 'command'.</para>
Defaults to 'command'.</para>
</entry>
</row>
<row>
@@ -1405,7 +1409,7 @@
</entry>
<entry>
<para>Name of the model attribute under which the form object is exposed.
Defaults to 'command'.</para>
Defaults to 'command'.</para>
</entry>
</row>
<row>
@@ -1622,10 +1626,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.hidden">
<section xml:id="spring-form.tld.hidden">
<title>The <literal>hidden</literal> tag</title>
<para>Renders an HTML 'input' tag with type 'hidden' using the bound value.</para>
<table id="spring-form.tld.hidden.table">
<table xml:id="spring-form.tld.hidden.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -1687,10 +1691,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.input">
<section xml:id="spring-form.tld.input">
<title>The <literal>input</literal> tag</title>
<para>Renders an HTML 'input' tag with type 'text' using the bound value.</para>
<table id="spring-form.tld.input.table">
<table xml:id="spring-form.tld.input.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -2144,10 +2148,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.label">
<section xml:id="spring-form.tld.label">
<title>The <literal>label</literal> tag</title>
<para>Renders a form field label in an HTML 'label' tag.</para>
<table id="spring-form.tld.label.table">
<table xml:id="spring-form.tld.label.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -2461,10 +2465,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.option">
<section xml:id="spring-form.tld.option">
<title>The <literal>option</literal> tag</title>
<para>Renders a single HTML 'option'. Sets 'selected' as appropriate based on bound value.</para>
<table id="spring-form.tld.option.table">
<table xml:id="spring-form.tld.option.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -2792,10 +2796,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.options">
<section xml:id="spring-form.tld.options">
<title>The <literal>options</literal> tag</title>
<para>Renders a list of HTML 'option' tags. Sets 'selected' as appropriate based on bound value.</para>
<table id="spring-form.tld.options.table">
<table xml:id="spring-form.tld.options.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -3137,10 +3141,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.password">
<section xml:id="spring-form.tld.password">
<title>The <literal>password</literal> tag</title>
<para>Renders an HTML 'input' tag with type 'password' using the bound value.</para>
<table id="spring-form.tld.password.table">
<table xml:id="spring-form.tld.password.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -3608,10 +3612,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.radiobutton">
<section xml:id="spring-form.tld.radiobutton">
<title>The <literal>radiobutton</literal> tag</title>
<para>Renders an HTML 'input' tag with type 'radio'.</para>
<table id="spring-form.tld.radiobutton.table">
<table xml:id="spring-form.tld.radiobutton.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -4009,10 +4013,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.radiobuttons">
<section xml:id="spring-form.tld.radiobuttons">
<title>The <literal>radiobuttons</literal> tag</title>
<para>Renders multiple HTML 'input' tags with type 'radio'.</para>
<table id="spring-form.tld.radiobuttons.table">
<table xml:id="spring-form.tld.radiobuttons.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -4452,10 +4456,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.select">
<section xml:id="spring-form.tld.select">
<title>The <literal>select</literal> tag</title>
<para>Renders an HTML 'select' element. Supports databinding to the selected option.</para>
<table id="spring-form.tld.select.table">
<table xml:id="spring-form.tld.select.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -4895,10 +4899,10 @@
</tgroup>
</table>
</section>
<section id="spring-form.tld.textarea">
<section xml:id="spring-form.tld.textarea">
<title>The <literal>textarea</literal> tag</title>
<para>Renders an HTML 'textarea'.</para>
<table id="spring-form.tld.textarea.table">
<table xml:id="spring-form.tld.textarea.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>

View File

@@ -1,59 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<appendix xml:id="spring.tld"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="spring.tld">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>spring.tld</title>
<section id="spring.tld-intro">
<section xml:id="spring.tld-intro">
<title>Introduction</title>
<para>One of the view technologies you can use with the Spring Framework
is Java Server Pages (JSPs). To help you implement views using Java Server Pages
the Spring Framework provides you with some tags for evaluating errors, setting
themes and outputting internationalized messages.</para>
<para>Please note that the various tags generated by this form tag library
are compliant with the <link xl:href="http://www.w3.org/TR/xhtml1/">XHTML-1.0-Strict specification</link> and attendant <link xl:href="http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict">DTD</link>.</para>
<para>This appendix describes the <literal>spring.tld</literal> tag library.</para>
<itemizedlist>
<listitem>
<xref linkend="spring.tld.bind"/>
</listitem>
<listitem>
<xref linkend="spring.tld.escapeBody"/>
</listitem>
<listitem>
<xref linkend="spring.tld.hasBindErrors"/>
</listitem>
<listitem>
<xref linkend="spring.tld.htmlEscape"/>
</listitem>
<listitem>
<xref linkend="spring.tld.message"/>
</listitem>
<listitem>
<xref linkend="spring.tld.nestedPath"/>
</listitem>
<listitem>
<xref linkend="spring.tld.theme"/>
</listitem>
<listitem>
<xref linkend="spring.tld.transform"/>
</listitem>
<listitem>
<xref linkend="spring.tld.url"/>
</listitem>
<listitem>
<xref linkend="spring.tld.eval"/>
</listitem>
</itemizedlist>
</section>
<para>One of the view technologies you can use with the Spring Framework
is Java Server Pages (JSPs). To help you implement views using Java Server Pages
the Spring Framework provides you with some tags for evaluating errors, setting
themes and outputting internationalized messages.</para>
<para>Please note that the various tags generated by this form tag library
are compliant with the <ulink url="http://www.w3.org/TR/xhtml1/">XHTML-1.0-Strict specification</ulink> and attendant <ulink url="http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict">DTD</ulink>.</para>
<para>This appendix describes the <literal>spring.tld</literal> tag library.</para>
<itemizedlist>
<listitem>
<xref linkend="spring.tld.bind"/>
</listitem>
<listitem>
<xref linkend="spring.tld.escapeBody"/>
</listitem>
<listitem>
<xref linkend="spring.tld.hasBindErrors"/>
</listitem>
<listitem>
<xref linkend="spring.tld.htmlEscape"/>
</listitem>
<listitem>
<xref linkend="spring.tld.message"/>
</listitem>
<listitem>
<xref linkend="spring.tld.nestedPath"/>
</listitem>
<listitem>
<xref linkend="spring.tld.theme"/>
</listitem>
<listitem>
<xref linkend="spring.tld.transform"/>
</listitem>
<listitem>
<xref linkend="spring.tld.url"/>
</listitem>
<listitem>
<xref linkend="spring.tld.eval"/>
</listitem>
</itemizedlist>
<section id="spring.tld.bind">
<section xml:id="spring.tld.bind">
<title>The <literal>bind</literal> tag</title>
<para>
Provides BindStatus object for the given bind path.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table id="spring.tld.bind.table">
Provides BindStatus object for the given bind path.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table xml:id="spring.tld.bind.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -81,7 +85,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as boolean value. Overrides
the default HTML escaping setting for the current page.</para>
the default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -110,9 +114,9 @@
</entry>
<entry>
<para>The path to the bean or bean property to bind status
information for. For instance account.name, company.address.zipCode
or just employee. The status object will exported to the page scope,
specifically for this bean or bean property</para>
information for. For instance account.name, company.address.zipCode
or just employee. The status object will exported to the page scope,
specifically for this bean or bean property</para>
</entry>
</row>
</tbody>
@@ -120,14 +124,14 @@
</table>
</section>
<section id="spring.tld.escapeBody">
<section xml:id="spring.tld.escapeBody">
<title>The <literal>escapeBody</literal> tag</title>
<para>
Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table id="spring.tld.escapeBody.table">
Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table xml:id="spring.tld.escapeBody.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -155,7 +159,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as boolean value. Overrides the
default HTML escaping setting for the current page.</para>
default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -170,21 +174,21 @@
</entry>
<entry>
<para>Set JavaScript escaping for this tag, as boolean value.
Default is false.</para>
Default is false.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.hasBindErrors">
<section xml:id="spring.tld.hasBindErrors">
<title>The <literal>hasBindErrors</literal> tag</title>
<para>
Provides Errors instance in case of bind errors.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table id="spring.tld.hasBindErrors.table">
Provides Errors instance in case of bind errors.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table xml:id="spring.tld.hasBindErrors.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -212,7 +216,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as boolean value.
Overrides the default HTML escaping setting for the current page.</para>
Overrides the default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -227,21 +231,21 @@
</entry>
<entry>
<para>The name of the bean in the request, that needs to be
inspected for errors. If errors are available for this bean, they
will be bound under the 'errors' key.</para>
inspected for errors. If errors are available for this bean, they
will be bound under the 'errors' key.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.htmlEscape">
<section xml:id="spring.tld.htmlEscape">
<title>The <literal>htmlEscape</literal> tag</title>
<para>
Sets default HTML escape value for the current page.
Overrides a "defaultHtmlEscape" context-param in web.xml, if any.
</para>
<table id="spring.tld.htmlEscape.table">
Sets default HTML escape value for the current page.
Overrides a "defaultHtmlEscape" context-param in web.xml, if any.
</para>
<table xml:id="spring.tld.htmlEscape.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -269,21 +273,21 @@
</entry>
<entry>
<para>Set the default value for HTML escaping, to be put
into the current PageContext.</para>
into the current PageContext.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.message">
<section xml:id="spring.tld.message">
<title>The <literal>message</literal> tag</title>
<para>
Retrieves the message with the given code, or text if code isn't resolvable.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table id="spring.tld.message.table">
Retrieves the message with the given code, or text if code isn't resolvable.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table xml:id="spring.tld.message.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -311,9 +315,9 @@
</entry>
<entry>
<para>Set optional message arguments for this tag, as a
(comma-)delimited String (each String argument can contain JSP EL),
an Object array (used as argument array), or a single Object (used
as single argument).</para>
(comma-)delimited String (each String argument can contain JSP EL),
an Object array (used as argument array), or a single Object (used
as single argument).</para>
</entry>
</row>
<row>
@@ -328,7 +332,7 @@
</entry>
<entry>
<para>The separator character to be used for splitting the
arguments string value; defaults to a 'comma' (',').</para>
arguments string value; defaults to a 'comma' (',').</para>
</entry>
</row>
<row>
@@ -343,7 +347,7 @@
</entry>
<entry>
<para>The code (key) to use when looking up the message.
If code is not provided, the text attribute will be used.</para>
If code is not provided, the text attribute will be used.</para>
</entry>
</row>
<row>
@@ -358,7 +362,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as boolean value.
Overrides the default HTML escaping setting for the current page.</para>
Overrides the default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -387,12 +391,12 @@
</entry>
<entry>
<para>A MessageSourceResolvable argument (direct or through JSP EL).
Fits nicely when used in conjunction with Spring's own validation error
classes which all implement the MessageSourceResolvable interface. For
example, this allows you to iterate over all of the errors in a form,
passing each error (using a runtime expression) as the value of this
'message' attribute, thus effecting the easy display of such error
messages.</para>
Fits nicely when used in conjunction with Spring's own validation error
classes which all implement the MessageSourceResolvable interface. For
example, this allows you to iterate over all of the errors in a form,
passing each error (using a runtime expression) as the value of this
'message' attribute, thus effecting the easy display of such error
messages.</para>
</entry>
</row>
<row>
@@ -407,8 +411,8 @@
</entry>
<entry>
<para>The scope to use when exporting the result to a variable.
This attribute is only used when var is also set. Possible values are
page, request, session and application.</para>
This attribute is only used when var is also set. Possible values are
page, request, session and application.</para>
</entry>
</row>
<row>
@@ -423,8 +427,8 @@
</entry>
<entry>
<para>Default text to output when a message for the given code
could not be found. If both text and code are not set, the tag will
output null.</para>
could not be found. If both text and code are not set, the tag will
output null.</para>
</entry>
</row>
<row>
@@ -439,20 +443,20 @@
</entry>
<entry>
<para>The string to use when binding the result to the page,
request, session or application scope. If not specified, the result
gets outputted to the writer (i.e. typically directly to the JSP).</para>
request, session or application scope. If not specified, the result
gets outputted to the writer (i.e. typically directly to the JSP).</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.nestedPath">
<section xml:id="spring.tld.nestedPath">
<title>The <literal>nestedPath</literal> tag</title>
<para>
Sets a nested path to be used by the bind tag's path.
</para>
<table id="spring.tld.nestedPath.table">
Sets a nested path to be used by the bind tag's path.
</para>
<table xml:id="spring.tld.nestedPath.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -480,22 +484,22 @@
</entry>
<entry>
<para>Set the path that this tag should apply. E.g. 'customer'
to allow bind paths like 'address.street' rather than
'customer.address.street'.</para>
to allow bind paths like 'address.street' rather than
'customer.address.street'.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.theme">
<section xml:id="spring.tld.theme">
<title>The <literal>theme</literal> tag</title>
<para>
Retrieves the theme message with the given code, or text if code isn't resolvable.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table id="spring.tld.theme.table">
Retrieves the theme message with the given code, or text if code isn't resolvable.
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
</para>
<table xml:id="spring.tld.theme.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -523,9 +527,9 @@
</entry>
<entry>
<para>Set optional message arguments for this tag, as a
(comma-)delimited String (each String argument can contain JSP EL),
an Object array (used as argument array), or a single Object (used
as single argument).</para>
(comma-)delimited String (each String argument can contain JSP EL),
an Object array (used as argument array), or a single Object (used
as single argument).</para>
</entry>
</row>
<row>
@@ -540,7 +544,7 @@
</entry>
<entry>
<para>The separator character to be used for splitting the
arguments string value; defaults to a 'comma' (',').</para>
arguments string value; defaults to a 'comma' (',').</para>
</entry>
</row>
<row>
@@ -555,7 +559,7 @@
</entry>
<entry>
<para>The code (key) to use when looking up the message.
If code is not provided, the text attribute will be used.</para>
If code is not provided, the text attribute will be used.</para>
</entry>
</row>
<row>
@@ -570,7 +574,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as boolean value.
Overrides the default HTML escaping setting for the current page.</para>
Overrides the default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -613,8 +617,8 @@
</entry>
<entry>
<para>The scope to use when exporting the result to a variable.
This attribute is only used when var is also set. Possible values are
page, request, session and application.</para>
This attribute is only used when var is also set. Possible values are
page, request, session and application.</para>
</entry>
</row>
<row>
@@ -629,8 +633,8 @@
</entry>
<entry>
<para>Default text to output when a message for the given code
could not be found. If both text and code are not set, the tag will
output null.</para>
could not be found. If both text and code are not set, the tag will
output null.</para>
</entry>
</row>
<row>
@@ -645,23 +649,23 @@
</entry>
<entry>
<para>The string to use when binding the result to the page,
request, session or application scope. If not specified, the result
gets outputted to the writer (i.e. typically directly to the JSP).</para>
request, session or application scope. If not specified, the result
gets outputted to the writer (i.e. typically directly to the JSP).</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.transform">
<section xml:id="spring.tld.transform">
<title>The <literal>transform</literal> tag</title>
<para>
Provides transformation of variables to Strings, using an appropriate
custom PropertyEditor from BindTag (can only be used inside BindTag).
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a 'defaultHtmlEscape' context-param in web.xml).
</para>
<table id="spring.tld.transform.table">
Provides transformation of variables to Strings, using an appropriate
custom PropertyEditor from BindTag (can only be used inside BindTag).
The HTML escaping flag participates in a page-wide or application-wide setting
(i.e. by HtmlEscapeTag or a 'defaultHtmlEscape' context-param in web.xml).
</para>
<table xml:id="spring.tld.transform.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -689,7 +693,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as boolean value. Overrides
the default HTML escaping setting for the current page.</para>
the default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -704,8 +708,8 @@
</entry>
<entry>
<para>The scope to use when exported the result to a variable.
This attribute is only used when var is also set. Possible values are
page, request, session and application.</para>
This attribute is only used when var is also set. Possible values are
page, request, session and application.</para>
</entry>
</row>
<row>
@@ -720,8 +724,8 @@
</entry>
<entry>
<para>The value to transform. This is the actual object you want
to have transformed (for instance a Date). Using the PropertyEditor that
is currently in use by the 'spring:bind' tag.</para>
to have transformed (for instance a Date). Using the PropertyEditor that
is currently in use by the 'spring:bind' tag.</para>
</entry>
</row>
<row>
@@ -736,21 +740,21 @@
</entry>
<entry>
<para>The string to use when binding the result to the page,
request, session or application scope. If not specified, the result gets
outputted to the writer (i.e. typically directly to the JSP).</para>
request, session or application scope. If not specified, the result gets
outputted to the writer (i.e. typically directly to the JSP).</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.url">
<section xml:id="spring.tld.url">
<title>The <literal>url</literal> tag</title>
<para>
Creates URLs with support for URI template variables, HTML/XML escaping, and Javascript escaping.
Modeled after the JSTL c:url tag with backwards compatibility in mind.
</para>
<table id="spring.tld.url.table">
Creates URLs with support for URI template variables, HTML/XML escaping, and Javascript escaping.
Modeled after the JSTL c:url tag with backwards compatibility in mind.
</para>
<table xml:id="spring.tld.url.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -777,9 +781,9 @@
<para>true</para>
</entry>
<entry>
<para>The URL to build. This value can include template {placeholders}
that are replaced with the URL encoded value of the named parameter. Parameters
must be defined using the param tag inside the body of this tag.</para>
<para>The URL to build. This value can include template {placeholders}
that are replaced with the URL encoded value of the named parameter. Parameters
must be defined using the param tag inside the body of this tag.</para>
</entry>
</row>
<row>
@@ -793,8 +797,8 @@
<para>true</para>
</entry>
<entry>
<para>Specifies a remote application context path. The default is the
current application context path.</para>
<para>Specifies a remote application context path. The default is the
current application context path.</para>
</entry>
</row>
<row>
@@ -823,9 +827,9 @@
<para>true</para>
</entry>
<entry>
<para>The scope for the var. 'application', 'session', 'request' and
'page' scopes are supported. Defaults to page scope. This attribute has no
effect unless the var attribute is also defined.</para>
<para>The scope for the var. 'application', 'session', 'request' and
'page' scopes are supported. Defaults to page scope. This attribute has no
effect unless the var attribute is also defined.</para>
</entry>
</row>
<row>
@@ -840,7 +844,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as a boolean value. Overrides the
default HTML escaping setting for the current page.</para>
default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -855,19 +859,19 @@
</entry>
<entry>
<para>Set JavaScript escaping for this tag, as a boolean value.
Default is false.</para>
Default is false.</para>
</entry>
</row>
</tbody>
</tbody>
</tgroup>
</table>
</section>
<section id="spring.tld.eval">
</section>
<section xml:id="spring.tld.eval">
<title>The <literal>eval</literal> tag</title>
<para>
Evaluates a Spring expression (SpEL) and either prints the result or assigns it to a variable.
</para>
<table id="spring.tld.eval.table">
Evaluates a Spring expression (SpEL) and either prints the result or assigns it to a variable.
</para>
<table xml:id="spring.tld.eval.table">
<title>Attributes</title>
<tgroup cols="4">
<colspec align="center" colname="Attribute"/>
@@ -923,9 +927,9 @@
<para>true</para>
</entry>
<entry>
<para>The scope for the var. 'application', 'session', 'request' and
'page' scopes are supported. Defaults to page scope. This attribute has no
effect unless the var attribute is also defined.</para>
<para>The scope for the var. 'application', 'session', 'request' and
'page' scopes are supported. Defaults to page scope. This attribute has no
effect unless the var attribute is also defined.</para>
</entry>
</row>
<row>
@@ -940,7 +944,7 @@
</entry>
<entry>
<para>Set HTML escaping for this tag, as a boolean value. Overrides the
default HTML escaping setting for the current page.</para>
default HTML escaping setting for the current page.</para>
</entry>
</row>
<row>
@@ -955,10 +959,10 @@
</entry>
<entry>
<para>Set JavaScript escaping for this tag, as a boolean value.
Default is false.</para>
Default is false.</para>
</entry>
</row>
</tbody>
</tbody>
</tgroup>
</table>
</section>

View File

@@ -1,7 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<sidebar xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<sidebar
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Spring Web Flow</title>
<para>Spring Web Flow (SWF) aims to be the best solution for the management
@@ -18,6 +23,6 @@
that drive business processes.</para>
<para>For more information about SWF, consult the
<ulink url="http://www.springframework.org/webflow">Spring Web Flow website</ulink>.
<link xl:href="http://www.springframework.org/webflow">Spring Web Flow website</link>.
</para>
</sidebar>

View File

@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.0" xml:id="testing" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:ns5="http://www.w3.org/1999/xhtml"
xmlns:ns4="http://www.w3.org/2000/svg"
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
xmlns:ns="http://docbook.org/ns/docbook">
<chapter
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Testing</title>
<section xml:id="testing-introduction">
@@ -83,9 +85,9 @@
usage with Spring's Web MVC framework, which are useful for testing
web contexts and controllers. These mock objects are generally more
convenient to use than dynamic mock objects such as <link
xlink:href="http://www.easymock.org">EasyMock</link> or existing
xl:href="http://www.easymock.org">EasyMock</link> or existing
Servlet API mock objects such as <link
xlink:href="http://www.mockobjects.com">MockObjects</link>.</para>
xl:href="http://www.mockobjects.com">MockObjects</link>.</para>
</section>
<section xml:id="mock-objects-portlet">
@@ -1358,10 +1360,10 @@ public class MyTest {
// static inner Config class</lineannotation>
<emphasis role="bold">@ContextConfiguration</emphasis>
public class OrderServiceTest {
@Configuration
static class Config {
<lineannotation>// this bean will be injected into the OrderServiceTest class</lineannotation>
@Bean
public OrderService orderService() {
@@ -1370,10 +1372,10 @@ public class OrderServiceTest {
return orderService;
}
}
@Autowired
private OrderService orderService;
@Test
public void testOrderService() {
<lineannotation>// test the orderService</lineannotation>
@@ -1862,7 +1864,7 @@ public class TransferServiceTest {
Gradle it is important to make sure that the build framework does
not <emphasis>fork</emphasis> between tests. For example, if the
<link
xlink:href="http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#forkMode">forkMode</link>
xl:href="http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#forkMode">forkMode</link>
for the Maven Surefire plug-in is set to <literal>always</literal>
or <literal>pertest</literal>, the TestContext framework will not
be able to cache application contexts between test classes and the
@@ -1964,7 +1966,7 @@ public class TransferServiceTest {
public class HibernateTitleRepositoryTests {
<lineannotation>// this instance will be dependency injected by type</lineannotation>
<emphasis role="bold">@Autowired</emphasis>
<emphasis role="bold">@Autowired</emphasis>
private HibernateTitleRepository titleRepository;
@Test
@@ -2004,9 +2006,9 @@ public class HibernateTitleRepositoryTests {
looks like this:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&gt;
<lineannotation>&lt;!-- this bean will be injected into the HibernateTitleRepositoryTests class --&gt;</lineannotation>
@@ -2014,7 +2016,7 @@ public class HibernateTitleRepositoryTests {
role="bold">com.foo.repository.hibernate.HibernateTitleRepository</emphasis>"&gt;
&lt;property name="sessionFactory" ref="sessionFactory"/&gt;
&lt;/bean&gt;
&lt;bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;
<lineannotation>&lt;!-- configuration elided for brevity --&gt;</lineannotation>
@@ -2543,32 +2545,32 @@ public class HibernateClinicTests extends AbstractClinicTests { }
<itemizedlist>
<listitem>
<para><link xlink:href="http://www.junit.org/">JUnit</link>: <quote>
<para><link xl:href="http://www.junit.org/">JUnit</link>: <quote>
<emphasis>A programmer-oriented testing framework for Java</emphasis>
</quote>. Used by the Spring Framework in its test suite.</para>
</listitem>
<listitem>
<para><link xlink:href="http://testng.org/">TestNG</link>: A testing
<para><link xl:href="http://testng.org/">TestNG</link>: A testing
framework inspired by JUnit with added support for Java 5 annotations,
test groups, data-driven testing, distributed testing, etc.</para>
</listitem>
<listitem>
<para><link
xlink:href="http://www.mockobjects.com/">MockObjects.com</link>: Web
xl:href="http://www.mockobjects.com/">MockObjects.com</link>: Web
site dedicated to mock objects, a technique for improving the design
of code within test-driven development.</para>
</listitem>
<listitem>
<para><link
xlink:href="http://en.wikipedia.org/wiki/Mock_Object">"Mock
xl:href="http://en.wikipedia.org/wiki/Mock_Object">"Mock
Objects"</link>: Article in Wikipedia.</para>
</listitem>
<listitem>
<para><link xlink:href="http://www.easymock.org/">EasyMock</link>:
<para><link xl:href="http://www.easymock.org/">EasyMock</link>:
Java library <quote> <emphasis>that provides Mock Objects for
interfaces (and objects through the class extension) by generating
them on the fly using Java's proxy mechanism.</emphasis> </quote> Used
@@ -2576,27 +2578,27 @@ public class HibernateClinicTests extends AbstractClinicTests { }
</listitem>
<listitem>
<para><link xlink:href="http://www.jmock.org/">JMock</link>: Library
<para><link xl:href="http://www.jmock.org/">JMock</link>: Library
that supports test-driven development of Java code with mock
objects.</para>
</listitem>
<listitem>
<para><link xlink:href="http://mockito.org/">Mockito</link>: Java mock
<para><link xl:href="http://mockito.org/">Mockito</link>: Java mock
library based on the <link
xlink:href="http://xunitpatterns.com/Test%20Spy.html">test spy</link>
xl:href="http://xunitpatterns.com/Test%20Spy.html">test spy</link>
pattern.</para>
</listitem>
<listitem>
<para><link xlink:href="http://dbunit.sourceforge.net/">DbUnit</link>:
<para><link xl:href="http://dbunit.sourceforge.net/">DbUnit</link>:
JUnit extension (also usable with Ant and Maven) targeted for
database-driven projects that, among other things, puts your database
into a known state between test runs.</para>
</listitem>
<listitem>
<para><link xlink:href="http://grinder.sourceforge.net/">The
<para><link xl:href="http://grinder.sourceforge.net/">The
Grinder</link>: Java load testing framework.</para>
</listitem>
</itemizedlist>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- ==================================================================== -->
<t:titlepage t:element="book" t:wrapper="div" class="titlepage">
<t:titlepage-content t:side="recto">
<!--
<productname/>
-->
<title/>
<subtitle/>
<!--
<corpauthor/>
<authorgroup/>
<author/>
<mediaobject/>
-->
<othercredit/>
<releaseinfo/>
<copyright/>
<legalnotice/>
<pubdate/>
<revision/>
<revhistory/>
<abstract/>
</t:titlepage-content>
<t:titlepage-content t:side="verso">
</t:titlepage-content>
<t:titlepage-separator>
<hr/>
</t:titlepage-separator>
<t:titlepage-before t:side="recto">
</t:titlepage-before>
<t:titlepage-before t:side="verso">
</t:titlepage-before>
</t:titlepage>
</t:templates>

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!DOCTYPE t:templates [
<!ENTITY hsize0 "10pt">
<!ENTITY hsize1 "12pt">
<!ENTITY hsize2 "14.4pt">
<!ENTITY hsize3 "17.28pt">
<!ENTITY hsize4 "20.736pt">
<!ENTITY hsize5 "24.8832pt">
<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 -->
<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 -->
<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 -->
<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 -->
<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 -->
<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 -->
]>
<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<t:titlepage t:element="book" t:wrapper="fo:block">
<t:titlepage-content t:side="recto">
<title
t:named-template="division.title"
param:node="ancestor-or-self::book[1]"
text-align="center"
font-size="&hsize5;"
space-before="&hsize5space;"
font-weight="bold"
font-family="{$title.fontset}"/>
<subtitle
text-align="center"
font-size="&hsize4;"
space-before="&hsize4space;"
font-family="{$title.fontset}"/>
<!-- <corpauthor space-before="0.5em"
font-size="&hsize2;"/>
<authorgroup space-before="0.5em"
font-size="&hsize2;"/>
<author space-before="0.5em"
font-size="&hsize2;"/> -->
<mediaobject space-before="2em" space-after="2em"/>
<releaseinfo space-before="5em" font-size="&hsize2;"/>
<copyright space-before="1.5em"
font-weight="normal"
font-size="8"/>
<legalnotice space-before="5em"
font-weight="normal"
font-style="italic"
font-size="8"/>
<othercredit space-before="2em"
font-weight="normal"
font-size="8"/>
<pubdate space-before="0.5em"/>
<revision space-before="0.5em"/>
<revhistory space-before="0.5em"/>
<abstract space-before="0.5em"
text-align="start"
margin-left="0.5in"
margin-right="0.5in"
font-family="{$body.fontset}"/>
</t:titlepage-content>
<t:titlepage-content t:side="verso">
</t:titlepage-content>
<t:titlepage-separator>
</t:titlepage-separator>
<t:titlepage-before t:side="recto">
</t:titlepage-before>
<t:titlepage-before t:side="verso">
</t:titlepage-before>
</t:titlepage>
<!-- ==================================================================== -->
</t:templates>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="transaction"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="transaction">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Transaction Management</title>
<section id="transaction-intro">
<section xml:id="transaction-intro">
<title>Introduction to Spring Framework transaction management</title>
<para>Comprehensive transaction support is among the most compelling
@@ -83,7 +87,7 @@
</itemizedlist>
</section>
<section id="transaction-motivation">
<section xml:id="transaction-motivation">
<title>Advantages of the Spring Framework's transaction support model<!--Renamed section to make it more to the point. TR: OK--></title>
<para>Traditionally, Java EE developers have had two choices for
@@ -96,7 +100,7 @@
<!--Gave global, local, and spring models their own sections. These need to be called out at a higher level, esp. Spring advantage! TR: OK-->
<section id="transaction-global">
<section xml:id="transaction-global">
<title>Global transactions</title>
<para>Global transactions enable you to work with multiple transactional
@@ -126,7 +130,7 @@
compelling alternatives for declarative transaction management.</para>
</section>
<section id="transaction-local">
<section xml:id="transaction-local">
<title>Local transactions</title>
<para>Local transactions are resource-specific, such as a transaction
@@ -141,7 +145,7 @@
transactions are invasive to the programming model.</para>
</section>
<section id="transaction-programming-model">
<section xml:id="transaction-programming-model">
<title>Spring Framework's consistent programming model</title>
<para>Spring resolves the disadvantages of global and local
@@ -183,9 +187,9 @@ TR: OK AS IS - I think it's fine as is - the concepts apply to both programmatic
if your application needs to handle transactions across multiple
resources, which is not a requirement for many applications. Many
high-end applications use a single, highly scalable database (such as
Oracle RAC) instead. Standalone transaction managers such as <ulink
url="http://www.atomikos.com/">Atomikos Transactions</ulink> and
<ulink url="http://jotm.objectweb.org/">JOTM</ulink> are other
Oracle RAC) instead. Standalone transaction managers such as <link
xl:href="http://www.atomikos.com/">Atomikos Transactions</link> and
<link xl:href="http://jotm.objectweb.org/">JOTM</link> are other
options. Of course, you may need other application server capabilities
such as Java Message Service (JMS) and J2EE Connector Architecture
(JCA).</para>
@@ -199,14 +203,14 @@ TR: OK AS IS - I think it's fine as is - the concepts apply to both programmatic
Spring Framework, only some of the bean definitions in your
configuration file, rather than your code, need to change.</para>
<!--CLarify last sentence. Only what kind of configuration has to change?
<!--CLarify last sentence. Only what kind of configuration has to change?
TR: REVISED, PLS REVIEW - changed to say "some of the bean definitions in your configuration file"-->
</sidebar>
</section>
</section>
<section id="transaction-strategies">
<title>Understanding the Spring Framework transaction abstraction<!--If this section applies only to prog. tx management, we should say that up front. Add info?
<section xml:id="transaction-strategies">
<title>Understanding the Spring Framework transaction abstraction<!--If this section applies only to prog. tx management, we should say that up front. Add info?
TR: OK AS IS - It's relevant for declarative tx as well--></title>
<para>The key to the Spring transaction abstraction is the notion of a
@@ -228,7 +232,7 @@ TR: OK AS IS - It's relevant for declarative tx as well--></title>
<para>This is primarily a service provider interface (SPI), although it
can be used <link
linkend="transaction-programmatic-ptm">programmatically</link> from your
application code. <!--Write out SPI with SPI in parentheses. SPI stands for a number of different things.And does logic of sentence make sense?
application code. <!--Write out SPI with SPI in parentheses. SPI stands for a number of different things.And does logic of sentence make sense?
TR: REVISED, PLS REVIEW - spelled SPI out and added a bit of clarification at the end-->Because
<interfacename>PlatformTransactionManager</interfacename> is an
<emphasis>interface</emphasis>, it can be easily mocked or stubbed as
@@ -375,16 +379,16 @@ TR:REVISED, PLS REVIEW-->
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"&gt;
&lt;jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/&gt;
&lt;jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/&gt;
&lt;bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" /&gt;
<lineannotation>&lt;!-- other <literal>&lt;bean/&gt;</literal> definitions here --&gt;</lineannotation>
<lineannotation>&lt;!-- other &lt;bean/&gt; definitions here --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
@@ -470,7 +474,7 @@ TR:REVISED, PLS REVIEW-->
versa.</para>
</section>
<section id="tx-resource-synchronization">
<section xml:id="tx-resource-synchronization">
<title>Synchronizing resources with transactions</title>
<para>It should now be clear how you create different transaction
@@ -487,7 +491,7 @@ TR:REVISED, PLS REVIEW-->
through the relevant
<interfacename>PlatformTransactionManager</interfacename>.<!--I broke into two sentences. Last part of sentence unclear,revise to say what triggers tx synch. Revise sentences if necessray. TR: OK--></para>
<section id="tx-resource-synchronization-high">
<section xml:id="tx-resource-synchronization-high">
<title>High-level synchronization approach</title>
<para>The preferred approach is to use Spring's highest level template
@@ -504,7 +508,7 @@ TR:REVISED, PLS REVIEW-->
TR: REVISED, PLS REVIEW - I re-wrote this to match the current preferred approaches--></para>
</section>
<section id="tx-resource-synchronization-low">
<section xml:id="tx-resource-synchronization-low">
<title>Low-level synchronization approach</title>
<para>Classes such as <classname>DataSourceUtils</classname> (for JDBC),
@@ -553,12 +557,12 @@ TR: REVISED, PLS REVIEW - I re-wrote this to match the current preferred approac
occurs behind the scenes and you won't need to write any special
code.</para>
<!--I don't understand this. Why tell them to use DataSourceUtils and then say you will prefer Spring abstraction?
Why not give example of using Spring abstraction?
<!--I don't understand this. Why tell them to use DataSourceUtils and then say you will prefer Spring abstraction?
Why not give example of using Spring abstraction?
TR: OK AS IS - it's not the prefered way, but we need to cover this if someine decideds to use it-->
</section>
<section id="tx-resource-synchronization-tadsp">
<section xml:id="tx-resource-synchronization-tadsp">
<title><classname>TransactionAwareDataSourceProxy</classname></title>
<para>At the very lowest level exists the
@@ -579,7 +583,7 @@ TR: OK AS IS - it's and additional tool, rarely used, but needs to be documented
</section>
</section>
<section id="transaction-declarative">
<section xml:id="transaction-declarative">
<title>Declarative transaction management</title>
<note>
@@ -607,7 +611,7 @@ TR: OK AS IS - it's and additional tool, rarely used, but needs to be documented
<para>Unlike EJB CMT, which is tied to JTA, the Spring Framework's
declarative transaction management works in any environment. It can
work with JTA transactions or local transactions using JDBC, JPA,
Hibernate or JDO by simply adjusting the configuration files.<!--Indicate what kind of config changes? Changes to what
Hibernate or JDO by simply adjusting the configuration files.<!--Indicate what kind of config changes? Changes to what
TR: REVISED, PLS REVIEW - rewrote this to hoefully make it more clear--></para>
</listitem>
@@ -680,10 +684,10 @@ TR: REVISED, PLS REVIEW - rewrote this to hoefully make it more clear--></para>
EJB convention (roll back is automatic only on unchecked exceptions), it
is often useful to customize this behavior.</para>
<!--customize this so that what happens? TR: OK AS IS - i think - the option is to provide alternate rules for when a transaction
<!--customize this so that what happens? TR: OK AS IS - i think - the option is to provide alternate rules for when a transaction
would be rolled back, not necessarily following the EJB rules-->
<section id="tx-decl-explained">
<section xml:id="tx-decl-explained">
<title>Understanding the Spring Framework's declarative transaction
implementation</title>
@@ -713,7 +717,7 @@ would be rolled back, not necessarily following the EJB rules-->
<para>Conceptually, calling a method on a transactional proxy looks like
this...</para>
<!--I don't see this image in src file or in pdf. Maybe it was added to src after pdf was created?
<!--I don't see this image in src file or in pdf. Maybe it was added to src after pdf was created?
TR: OK AS IS. images don't show up in the editor, but they do show up in the generated docs-->
<para><mediaobject>
@@ -728,7 +732,7 @@ TR: OK AS IS. images don't show up in the editor, but they do show up in the gen
</mediaobject></para>
</section>
<section id="transaction-declarative-first-example">
<section xml:id="transaction-declarative-first-example">
<title>Example of declarative transaction implementation</title>
<para>Consider the following interface, and its attendant
@@ -792,42 +796,42 @@ public class DefaultFooService implements FooService {
transaction with read-write semantics. The following configuration is
explained in detail in the next few paragraphs.</para>
<programlisting language="xml"><lineannotation>&lt;!-- from the file <literal>'context.xml'</literal> --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- from the file 'context.xml' --&gt;</lineannotation>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
<lineannotation><emphasis role="bold">xmlns:tx="http://www.springframework.org/schema/tx"</emphasis></lineannotation>
<lineannotation>xmlns:tx="http://www.springframework.org/schema/tx"</lineannotation>
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
<lineannotation><emphasis role="bold">http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd</emphasis></lineannotation>
http://www.springframework.org/schema/aop
<lineannotation>http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd</lineannotation>
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
<lineannotation>&lt;!-- this is the service object that we want to make transactional --&gt;</lineannotation>
&lt;bean id="fooService" class="x.y.service.DefaultFooService"/&gt;
<lineannotation>&lt;!-- the transactional advice (what 'happens'; see the <literal>&lt;aop:advisor/&gt;</literal> bean below) --&gt;</lineannotation>
<lineannotation>&lt;!-- the transactional advice (what 'happens'; see the &lt;aop:advisor/&gt; bean below) --&gt;</lineannotation>
&lt;tx:advice id="txAdvice" transaction-manager="txManager"&gt;
<lineannotation>&lt;!-- the transactional semantics... --&gt;</lineannotation>
&lt;tx:attributes&gt;
<lineannotation>&lt;!-- all methods starting with <literal>'get'</literal> are read-only --&gt;</lineannotation>
<lineannotation>&lt;!-- all methods starting with 'get' are read-only --&gt;</lineannotation>
&lt;tx:method name="get*" read-only="true"/&gt;
<lineannotation>&lt;!-- other methods use the default transaction settings (see below) --&gt;</lineannotation>
&lt;tx:method name="*"/&gt;
&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;
<lineannotation>&lt;!-- ensure that the above transactional advice runs for any execution
of an operation defined by the <interfacename>FooService</interfacename> interface --&gt;</lineannotation>
of an operation defined by the FooService interface --&gt;</lineannotation>
&lt;aop:config&gt;
&lt;aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/&gt;
&lt;aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/&gt;
&lt;/aop:config&gt;
<lineannotation>&lt;!-- don't forget the <interfacename>DataSource</interfacename> --&gt;</lineannotation>
<lineannotation>&lt;!-- don't forget the DataSource --&gt;</lineannotation>
&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
&lt;property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/&gt;
&lt;property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/&gt;
@@ -835,12 +839,12 @@ public class DefaultFooService implements FooService {
&lt;property name="password" value="tiger"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- similarly, don't forget the <interfacename>PlatformTransactionManager</interfacename> --&gt;</lineannotation>
<lineannotation>&lt;!-- similarly, don't forget the PlatformTransactionManager --&gt;</lineannotation>
&lt;bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
&lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- other <literal>&lt;bean/&gt;</literal> definitions here --&gt;</lineannotation>
<lineannotation>&lt;!-- other &lt;bean/&gt; definitions here --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
@@ -910,7 +914,7 @@ public class DefaultFooService implements FooService {
<para>The above configuration will be used to create a transactional
proxy around the object that is created from the
<literal>fooService</literal> bean definition. <!--Clarify what you mean by around the object; do you mean associated with the object? Revise to clarify. Around is vague.
<literal>fooService</literal> bean definition. <!--Clarify what you mean by around the object; do you mean associated with the object? Revise to clarify. Around is vague.
TR: OK AS IS - around is used a lot in AOP, so I think the audience will understand this usage-->The
proxy will be configured with the transactional advice, so that when an
appropriate method is invoked <emphasis>on the proxy</emphasis>, a
@@ -933,27 +937,27 @@ TR: OK AS IS - around is used a lot in AOP, so I think the audience will underst
UnsupportedOperationException thrown by the insertFoo(..) method of the
DefaultFooService class have been truncated for clarity.)</para>
<programlisting language="xml"> <lineannotation><emphasis role="bold">&lt;!-- the Spring container is starting up... --&gt;</emphasis></lineannotation>
<programlisting language="xml"> <lineannotation>&lt;!-- the Spring container is starting up... --&gt;</lineannotation>
[AspectJInvocationContextExposingAdvisorAutoProxyCreator] - Creating implicit proxy
for bean 'fooService' with 0 common interceptors and 1 specific interceptors
<lineannotation><emphasis role="bold">&lt;!-- the <classname>DefaultFooService</classname> is actually proxied --&gt;</emphasis></lineannotation>
<lineannotation>&lt;!-- the DefaultFooService is actually proxied --&gt;</lineannotation>
[JdkDynamicAopProxy] - Creating JDK dynamic proxy for [x.y.service.DefaultFooService]
<lineannotation><emphasis role="bold">&lt;!-- ... the <literal>insertFoo(..)</literal> method is now being invoked on the proxy --&gt;</emphasis></lineannotation>
<lineannotation>&lt;!-- ... the insertFoo(..) method is now being invoked on the proxy --&gt;</lineannotation>
[TransactionInterceptor] - Getting transaction for x.y.service.FooService.insertFoo
<lineannotation><emphasis role="bold">&lt;!-- the transactional advice kicks in here... --&gt;</emphasis></lineannotation>
<lineannotation>&lt;!-- the transactional advice kicks in here... --&gt;</lineannotation>
[DataSourceTransactionManager] - Creating new transaction with name [x.y.service.FooService.insertFoo]
[DataSourceTransactionManager] - Acquired Connection
[org.apache.commons.dbcp.PoolableConnection@a53de4] for JDBC transaction
<lineannotation><emphasis role="bold">&lt;!-- the <literal>insertFoo(..)</literal> method from <classname>DefaultFooService</classname> throws an exception... --&gt;</emphasis></lineannotation>
<lineannotation>&lt;!-- the insertFoo(..) method from DefaultFooService throws an exception... --&gt;</lineannotation>
[RuleBasedTransactionAttribute] - Applying rules to determine whether transaction should
rollback on java.lang.UnsupportedOperationException
[TransactionInterceptor] - Invoking rollback for transaction on x.y.service.FooService.insertFoo
due to throwable [java.lang.UnsupportedOperationException]
<lineannotation><emphasis role="bold">&lt;!-- and the transaction is rolled back (by default, <exceptionname>RuntimeException</exceptionname> instances cause rollback) --&gt;</emphasis></lineannotation>
<lineannotation>&lt;!-- and the transaction is rolled back (by default, RuntimeException instances cause rollback) --&gt;</lineannotation>
[DataSourceTransactionManager] - Rolling back JDBC transaction on Connection
[org.apache.commons.dbcp.PoolableConnection@a53de4]
[DataSourceTransactionManager] - Releasing JDBC Connection after transaction
@@ -961,12 +965,12 @@ TR: OK AS IS - around is used a lot in AOP, so I think the audience will underst
Exception in thread "main" java.lang.UnsupportedOperationException
at x.y.service.DefaultFooService.insertFoo(DefaultFooService.java:14)
<lineannotation><emphasis role="bold">&lt;!-- AOP infrastructure stack trace elements removed for clarity --&gt;</emphasis></lineannotation>
<lineannotation>&lt;!-- AOP infrastructure stack trace elements removed for clarity --&gt;</lineannotation>
at $Proxy0.insertFoo(Unknown Source)
at Boot.main(Boot.java:11)</programlisting>
</section>
<section id="transaction-declarative-rolling-back">
<section xml:id="transaction-declarative-rolling-back">
<title>Rolling back a declarative transaction</title>
<para>The previous section outlined the basics of how to specify
@@ -982,7 +986,7 @@ Exception in thread "main" java.lang.UnsupportedOperationException
Framework's transaction infrastructure code will catch any unhandled
<exceptionname>Exception</exceptionname> as it bubbles up the call
stack, and make a determination whether to mark the transaction for
rollback.<!--I changed to *can be configured* because next sentence says it does not do this by default in all cases.
rollback.<!--I changed to *can be configured* because next sentence says it does not do this by default in all cases.
TR: REVISED, PLS REVIEW. I changed it to *in its default configuration*BT: I STILL DON'T GET IT. PRECEDING SENTENCE AND FOLLOWING --><!--SENTENCE SEEM CONTRADICTORY. TR: REVISED AGAIN, PLS REVIEW.--></para>
<para>In its default configuration, the Spring Framework's transaction
@@ -994,7 +998,7 @@ TR: REVISED, PLS REVIEW. I changed it to *in its default configuration*BT: I STI
in a rollback). Checked exceptions that are thrown from a transactional
method do <emphasis>not</emphasis> result in rollback in the default
configuration.<!--I revised preceding because it says ONLY first case is rolled back by default, but then says Errors are also marked by default.
TR: OK AS IS. Errors aren't thrown by application code, only checked or unchecked exceptions are. So the Errors part is just clarifying that
TR: OK AS IS. Errors aren't thrown by application code, only checked or unchecked exceptions are. So the Errors part is just clarifying that
if the underlying application server infrastructure throws an Error the transaction will be rolled back.--></para>
<para>You can configure exactly which
@@ -1006,8 +1010,7 @@ if the underlying application server infrastructure throws an Error the transact
<programlisting language="xml">&lt;tx:advice id="txAdvice" transaction-manager="txManager"&gt;
&lt;tx:attributes&gt;
&lt;tx:method name="get*" read-only="true" <lineannotation><emphasis
role="bold">rollback-for="NoProductInStockException"</emphasis></lineannotation>/&gt;
&lt;tx:method name="get*" read-only="true" <lineannotation>rollback-for="NoProductInStockException"</lineannotation>/&gt;
&lt;tx:method name="*"/&gt;
&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;</programlisting>
@@ -1021,7 +1024,7 @@ if the underlying application server infrastructure throws an Error the transact
<programlisting language="xml">&lt;tx:advice id="txAdvice"&gt;
&lt;tx:attributes&gt;
&lt;tx:method name="updateStock" <lineannotation><emphasis role="bold">no-rollback-for="InstrumentNotFoundException"</emphasis></lineannotation>/&gt;
&lt;tx:method name="updateStock" <lineannotation>no-rollback-for="InstrumentNotFoundException"</lineannotation>/&gt;
&lt;tx:method name="*"/&gt;
&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;</programlisting>
@@ -1060,7 +1063,7 @@ if the underlying application server infrastructure throws an Error the transact
clean POJO-based architecture.</para>
</section>
<section id="transaction-declarative-diff-tx">
<section xml:id="transaction-declarative-diff-tx">
<title>Configuring different transactional semantics for different
beans</title>
@@ -1084,11 +1087,11 @@ if the underlying application server infrastructure throws an Error the transact
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;aop:config&gt;
@@ -1115,7 +1118,7 @@ if the underlying application server infrastructure throws an Error the transact
&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;
<lineannotation>&lt;!-- other transaction infrastructure beans such as a <interfacename>PlatformTransactionManager</interfacename> omitted... --&gt;</lineannotation>
<lineannotation>&lt;!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
@@ -1128,11 +1131,11 @@ if the underlying application server infrastructure throws an Error the transact
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;aop:config&gt;
@@ -1149,7 +1152,7 @@ if the underlying application server infrastructure throws an Error the transact
&lt;/aop:config&gt;
<lineannotation>&lt;!-- this bean will be transactional (see the <literal>'defaultServiceOperation'</literal> pointcut) --&gt;</lineannotation>
<lineannotation>&lt;!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) --&gt;</lineannotation>
&lt;bean id="fooService" class="x.y.service.DefaultFooService"/&gt;
<lineannotation>&lt;!-- this bean will also be transactional, but with totally different transactional settings --&gt;</lineannotation>
@@ -1168,12 +1171,12 @@ if the underlying application server infrastructure throws an Error the transact
&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;
<lineannotation>&lt;!-- other transaction infrastructure beans such as a <interfacename>PlatformTransactionManager</interfacename> omitted... --&gt;</lineannotation>
<lineannotation>&lt;!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
</section>
<section id="transaction-declarative-txadvice-settings">
<section xml:id="transaction-declarative-txadvice-settings">
<title><literal>&lt;tx:advice/&gt;</literal> settings</title>
<para>This section summarizes the various transactional settings that
@@ -1213,7 +1216,7 @@ if the underlying application server infrastructure throws an Error the transact
<literal>&lt;tx:attributes/&gt;</literal> tags are summarized
below:</para>
<para><table id="tx-method-settings">
<para><table xml:id="tx-method-settings">
<title><literal>&lt;tx:method/&gt;</literal> settings</title>
<tgroup cols="4">
@@ -1322,7 +1325,7 @@ if the underlying application server infrastructure throws an Error the transact
</table></para>
</section>
<section id="transaction-declarative-annotations">
<section xml:id="transaction-declarative-annotations">
<title>Using <interfacename>@Transactional</interfacename></title>
<para>In addition to the XML-based declarative approach to transaction
@@ -1354,33 +1357,33 @@ public class DefaultFooService implements FooService {
container, the bean instance can be made transactional by adding merely
<emphasis>one</emphasis> line of XML configuration:</para>
<programlisting language="xml"><lineannotation>&lt;!-- from the file <literal>'context.xml'</literal> --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- from the file 'context.xml' --&gt;</lineannotation>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
<lineannotation>&lt;!-- this is the service object that we want to make transactional --&gt;</lineannotation>
&lt;bean id="fooService" class="x.y.service.DefaultFooService"/&gt;
<lineannotation>&lt;!-- enable the configuration of transactional behavior based on annotations --&gt;</lineannotation>
<emphasis role="bold">&lt;tx:annotation-driven transaction-manager="txManager"/&gt;</emphasis>
<lineannotation>&lt;!-- a <interfacename>PlatformTransactionManager</interfacename> is still required --&gt;</lineannotation>
<lineannotation>&lt;!-- a PlatformTransactionManager is still required --&gt;</lineannotation>
&lt;bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
<lineannotation>&lt;!-- (this dependency is defined somewhere else) --&gt;</lineannotation>
&lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- other <literal>&lt;bean/&gt;</literal> definitions here --&gt;</lineannotation>
<lineannotation>&lt;!-- other &lt;bean/&gt; definitions here --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
@@ -1467,7 +1470,7 @@ public class DefaultFooService implements FooService {
order to turn <interfacename>@Transactional</interfacename> into runtime
behavior on any kind of method.</para>
<para><table id="tx-annotation-driven-settings">
<para><table xml:id="tx-annotation-driven-settings">
<title>Annotation driven transaction settings</title>
<tgroup cols="4">
@@ -1599,14 +1602,14 @@ public class DefaultFooService implements FooService {
<lineannotation>// do something</lineannotation>
}
<lineannotation>// <emphasis role="bold">these</emphasis> settings have precedence for this method</lineannotation>
<lineannotation>// these settings have precedence for this method</lineannotation>
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void updateFoo(Foo foo) {
<lineannotation>// do something</lineannotation>
}
}</programlisting>
<section id="transaction-declarative-attransactional-settings">
<section xml:id="transaction-declarative-attransactional-settings">
<title><interfacename>@Transactional</interfacename> settings</title>
<para>The <interfacename>@Transactional</interfacename> annotation is
@@ -1649,7 +1652,7 @@ public class DefaultFooService implements FooService {
the <interfacename>@Transactional</interfacename> annotation are
summarized in the following table:</para>
<para><table id="tx-attransactional-properties">
<para><table xml:id="tx-attransactional-properties">
<title><interfacename>@Transactional</interfacename>
properties</title>
@@ -1668,14 +1671,14 @@ public class DefaultFooService implements FooService {
<row>
<entry><literal><link
linkend="tx-multiple-tx-mgrs-with-attransactional">value</link></literal></entry>
<entry>String</entry>
<entry>
Optional qualifier specifying the transaction manager to be used.
</entry>
</row>
<row>
<entry><literal><link
linkend="tx-propagation">propagation</link></literal></entry>
@@ -1769,8 +1772,8 @@ public class DefaultFooService implements FooService {
the name of the transaction would be:
<literal>com.foo.BusinessService.handlePayment</literal>.</para>
</section>
<section id="tx-multiple-tx-mgrs-with-attransactional">
<section xml:id="tx-multiple-tx-mgrs-with-attransactional">
<title>Multiple Transaction Managers with <interfacename>@Transactional</interfacename></title>
<para>
Most Spring applications only need a single transaction manager, but there may be situations
@@ -1778,17 +1781,17 @@ public class DefaultFooService implements FooService {
The value attribute of the <interfacename>@Transactional</interfacename> annotation can
be used to optionally specify the identity of the <classname>PlatformTransactionManager</classname>
to be used. This can either be the bean name or the qualifier value of the transaction manager bean.
For example, using the qualifier notation, the following Java code
For example, using the qualifier notation, the following Java code
<programlisting language="java">
public class TransactionalService {
@Transactional("order")
public void setSomething(String name) { ... }
@Transactional("account")
public void doSomething() { ... }
}
</programlisting>
</programlisting>
could be combined with the following transaction manager bean declarations in the application context.
<programlisting language="xml"><![CDATA[
<tx:annotation-driven/>
@@ -1801,16 +1804,16 @@ public class DefaultFooService implements FooService {
<bean id="transactionManager2" class="org.springframework.jdbc.DataSourceTransactionManager">
...
<qualifier value="account"/>
</bean>
</bean>
]]>
</programlisting>
In this case, the two methods on <literal>TransactionalService</literal> will run under separate
transaction managers, differentiated by the "order" and "account" qualifiers.
The default <literal>&lt;tx:annotation-driven&gt;</literal> target bean name <literal>transactionManager</literal> will
still be used if no specifically qualified PlatformTransactionManager bean is found.
</programlisting>
In this case, the two methods on <literal>TransactionalService</literal> will run under separate
transaction managers, differentiated by the "order" and "account" qualifiers.
The default <literal>&lt;tx:annotation-driven&gt;</literal> target bean name <literal>transactionManager</literal> will
still be used if no specifically qualified PlatformTransactionManager bean is found.
</para>
</section>
<section id="tx-custom-attributes">
<section xml:id="tx-custom-attributes">
<title>Custom shortcut annotations</title>
<para>
If you find you are repeatedly using the same attributes with <interfacename>@Transactional</interfacename>
@@ -1822,34 +1825,34 @@ public class DefaultFooService implements FooService {
@Transactional("order")
public @interface OrderTx {
}
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("account")
public @interface AccountTx {
}
}
</programlisting>
allows us to write the example from the previous section as
<programlisting language="java">
public class TransactionalService {
@OrderTx
public void setSomething(String name) { ... }
@AccountTx
public void doSomething() { ... }
}
</programlisting>
Here we have used the syntax to define the transaction manager qualifier, but could also have
</programlisting>
Here we have used the syntax to define the transaction manager qualifier, but could also have
included propagation behavior, rollback rules, timeouts etc.
</para>
</section>
</section>
</section>
<section id="tx-propagation">
<section xml:id="tx-propagation">
<title>Transaction propagation</title>
<!--Changed heading to be more explicit. These are settings, right?
<!--Changed heading to be more explicit. These are settings, right?
TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section discusses propagation in general as well as the settings-->
<para>This section describes some semantics of transaction propagation
@@ -1862,7 +1865,7 @@ TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section d
transactions, and how the propagation setting applies to this
difference.</para>
<section id="tx-propagation-required">
<section xml:id="tx-propagation-required">
<title>Required</title>
<para><mediaobject>
@@ -1906,7 +1909,7 @@ TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section d
to indicate clearly that a rollback was performed instead.</para>
</section>
<section id="tx-propagation-requires_new">
<section xml:id="tx-propagation-requires_new">
<title>RequiresNew</title>
<para><mediaobject>
@@ -1928,7 +1931,7 @@ TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section d
transaction's rollback status.</para>
</section>
<section id="tx-propagation-nested">
<section xml:id="tx-propagation-nested">
<title>Nested</title>
<para><literal>PROPAGATION_NESTED</literal> uses a
@@ -1943,7 +1946,7 @@ TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section d
</section>
</section>
<section id="transaction-declarative-applying-more-than-just-tx-advice">
<section xml:id="transaction-declarative-applying-more-than-just-tx-advice">
<title>Advising transactional operations<!--Need better heading? Executing transactional advice? TR: OK AS IS--></title>
<para>Suppose you want to execute <emphasis>both</emphasis>
@@ -2010,7 +2013,7 @@ public class SimpleProfiler implements Ordered {
this.order = order;
}
<lineannotation>// this method <emphasis>is</emphasis> the around advice</lineannotation>
<lineannotation>// this method *is* the around advice</lineannotation>
public Object profile(ProceedingJoinPoint call) throws Throwable {
Object returnValue;
StopWatch clock = new StopWatch(getClass().getName());
@@ -2032,11 +2035,11 @@ public class SimpleProfiler implements Ordered {
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;bean id="fooService" class="x.y.service.DefaultFooService"/&gt;
@@ -2051,7 +2054,7 @@ public class SimpleProfiler implements Ordered {
role="bold">order="200"</emphasis>/&gt;
&lt;aop:config&gt;
<lineannotation>&lt;!-- this advice will execute <emphasis role="bold">around</emphasis> the transactional advice --&gt;</lineannotation>
<lineannotation>&lt;!-- this advice will execute around the transactional advice --&gt;</lineannotation>
&lt;aop:aspect id="profilingAspect" ref="profiler"&gt;
&lt;aop:pointcut id="serviceMethodWithReturnValue"
expression="execution(!void x.y..*Service.*(..))"/&gt;
@@ -2074,7 +2077,7 @@ public class SimpleProfiler implements Ordered {
<para>The result of the above configuration is a
<literal>fooService</literal> bean that has profiling and transactional
aspects applied to it <emphasis>in the desired order</emphasis>. <!--By *that order,* indicate whether you mean the numbered process or the above example? Or are they the same?
aspects applied to it <emphasis>in the desired order</emphasis>. <!--By *that order,* indicate whether you mean the numbered process or the above example? Or are they the same?
TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired order is profiling first followed by transactional aspect-->You
configure any number of additional aspects in similar fashion.</para>
@@ -2087,11 +2090,11 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
&lt;bean id="fooService" class="x.y.service.DefaultFooService"/&gt;
@@ -2127,7 +2130,7 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde
&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;
<lineannotation>&lt;!-- other &lt;bean/&gt; definitions such as a <interfacename>DataSource</interfacename> and a <interfacename>PlatformTransactionManager</interfacename> here --&gt;</lineannotation>
<lineannotation>&lt;!-- other &lt;bean/&gt; definitions such as a DataSource and a PlatformTransactionManager here --&gt;</lineannotation>
&lt;/beans&gt;</programlisting>
@@ -2143,7 +2146,7 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde
<para>You configure additional aspects in similar fashion.</para>
</section>
<section id="transaction-declarative-aspectj">
<section xml:id="transaction-declarative-aspectj">
<title>Using <interfacename>@Transactional</interfacename> with
AspectJ</title>
@@ -2175,7 +2178,7 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde
<programlisting language="java"><lineannotation>// construct an appropriate transaction manager </lineannotation>
DataSourceTransactionManager txManager = new DataSourceTransactionManager(getDataSource());
<lineannotation>// configure the <classname>AnnotationTransactionAspect</classname> to use it; this must be done before executing any transactional methods</lineannotation>
<lineannotation>// configure the AnnotationTransactionAspect to use it; this must be done before executing any transactional methods</lineannotation>
AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); </programlisting>
<note>
@@ -2197,15 +2200,15 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); </progr
<para>To weave your applications with the
<classname>AnnotationTransactionAspect</classname> you must either build
your application with AspectJ (see the <ulink
url="http://www.eclipse.org/aspectj/doc/released/devguide/index.html">AspectJ
Development Guide</ulink>) or use load-time weaving. See <xref
your application with AspectJ (see the <link
xl:href="http://www.eclipse.org/aspectj/doc/released/devguide/index.html">AspectJ
Development Guide</link>) or use load-time weaving. See <xref
linkend="aop-aj-ltw" /> for a discussion of load-time weaving with
AspectJ.</para>
</section>
</section>
<section id="transaction-programmatic">
<section xml:id="transaction-programmatic">
<title>Programmatic transaction management</title>
<para>The Spring Framework provides two means of programmatic transaction
@@ -2229,7 +2232,7 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); </progr
<interfacename>UserTransaction</interfacename> API, although exception
handling is less cumbersome.</para>
<section id="tx-prog-template">
<section xml:id="tx-prog-template">
<title>Using the <classname>TransactionTemplate</classname></title>
<para>The <classname>TransactionTemplate</classname> adopts the same
@@ -2261,10 +2264,10 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); </progr
<programlisting language="java">public class SimpleService implements Service {
<lineannotation>// single <classname>TransactionTemplate</classname> shared amongst all methods in this instance</lineannotation>
<lineannotation>// single TransactionTemplate shared amongst all methods in this instance</lineannotation>
private final TransactionTemplate transactionTemplate;
<lineannotation>// use constructor-injection to supply the <interfacename>PlatformTransactionManager</interfacename></lineannotation>
<lineannotation>// use constructor-injection to supply the PlatformTransactionManager</lineannotation>
public SimpleService(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
this.transactionTemplate = new TransactionTemplate(transactionManager);
@@ -2311,7 +2314,7 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); </progr
}
});</programlisting>
<section id="tx-prog-template-settings">
<section xml:id="tx-prog-template-settings">
<title>Specifying transaction settings</title>
<para>You can specify transaction settings such as the propagation
@@ -2350,21 +2353,21 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); </progr
&lt;property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/&gt;
&lt;property name="timeout" value="30"/&gt;
&lt;/bean&gt;"</programlisting>
</section>
<para>Finally, instances of the
<classname>TransactionTemplate</classname> class are threadsafe, in that
instances do not maintain any conversational state.
<classname>TransactionTemplate</classname> instances
<emphasis>do</emphasis> however maintain configuration state, so while a
number of classes may share a single instance of a
<classname>TransactionTemplate</classname>, if a class needs to use a
<classname>TransactionTemplate</classname> with different settings (for
example, a different isolation level), then you need to create two
distinct <classname>TransactionTemplate</classname> instances.</para>
<para>Finally, instances of the
<classname>TransactionTemplate</classname> class are threadsafe, in that
instances do not maintain any conversational state.
<classname>TransactionTemplate</classname> instances
<emphasis>do</emphasis> however maintain configuration state, so while a
number of classes may share a single instance of a
<classname>TransactionTemplate</classname>, if a class needs to use a
<classname>TransactionTemplate</classname> with different settings (for
example, a different isolation level), then you need to create two
distinct <classname>TransactionTemplate</classname> instances.</para>
</section>
</section>
<section id="transaction-programmatic-ptm">
<section xml:id="transaction-programmatic-ptm">
<title>Using the
<interfacename>PlatformTransactionManager</interfacename></title>
@@ -2394,7 +2397,7 @@ txManager.commit(status);</programlisting>
</section>
</section>
<section id="tx-decl-vs-prog">
<section xml:id="tx-decl-vs-prog">
<title>Choosing between programmatic and declarative transaction
management</title>
@@ -2416,7 +2419,7 @@ txManager.commit(status);</programlisting>
reduced.</para>
</section>
<section id="transaction-application-server-integration">
<section xml:id="transaction-application-server-integration">
<title>Application server-specific integration</title>
<para>Spring's transaction abstraction generally is application server
@@ -2451,7 +2454,7 @@ txManager.commit(status);</programlisting>
explicitly; rather, they are chosen automatically, with the standard
<classname>JtaTransactionManager</classname> as default fallback.</para>
<section id="transaction-application-server-integration-websphere">
<section xml:id="transaction-application-server-integration-websphere">
<title>IBM WebSphere</title>
<para>On WebSphere 6.1.0.9 and above, the recommended Spring JTA
@@ -2465,7 +2468,7 @@ txManager.commit(status);</programlisting>
IBM!</para>
</section>
<section id="transaction-application-server-integration-weblogic">
<section xml:id="transaction-application-server-integration-weblogic">
<title>BEA WebLogic Server</title>
<para>On WebLogic Server 9.0 or above, you typically would use the
@@ -2479,7 +2482,7 @@ txManager.commit(status);</programlisting>
transactions in all cases.</para>
</section>
<section id="transaction-application-server-integration-oc4j">
<section xml:id="transaction-application-server-integration-oc4j">
<title>Oracle OC4J</title>
<para>Spring ships a special adapter class for OC4J 10.1.3 or later
@@ -2496,10 +2499,10 @@ txManager.commit(status);</programlisting>
</section>
</section>
<section id="transaction-solutions-to-common-problems">
<section xml:id="transaction-solutions-to-common-problems">
<title>Solutions to common problems</title>
<section id="transaction-solutions-to-common-problems-wrong-ptm">
<section xml:id="transaction-solutions-to-common-problems-wrong-ptm">
<title>Use of the wrong transaction manager for a specific
<interfacename>DataSource</interfacename></title>
@@ -2521,7 +2524,7 @@ txManager.commit(status);</programlisting>
</section>
</section>
<section id="transaction-resources">
<section xml:id="transaction-resources">
<title>Further Resources</title>
<para>For more information about the Spring Framework's transaction
@@ -2529,18 +2532,18 @@ txManager.commit(status);</programlisting>
<itemizedlist>
<listitem>
<para><ulink
url="http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html">Distributed
transactions in Spring, with and without XA</ulink> is a JavaWorld
<para><link
xl:href="http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html">Distributed
transactions in Spring, with and without XA</link> is a JavaWorld
presentation in which SpringSource's David Syer guides you through
seven patterns for distributed transactions in Spring applications,
three of them with XA and four without.</para>
</listitem>
<listitem>
<para><ulink url="http://www.infoq.com/minibooks/JTDS">Java
Transaction Design Strategies</ulink> is a book available from <ulink
url="http://www.infoq.com/">InfoQ</ulink> that provides a well-paced
<para><link xl:href="http://www.infoq.com/minibooks/JTDS">Java
Transaction Design Strategies</link> is a book available from <link
xl:href="http://www.infoq.com/">InfoQ</link> that provides a well-paced
introduction to transactions in Java. It also includes side-by-side
examples of how to configure and use transactions with both the Spring
Framework and EJB3.</para>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="validation"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="validation">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Validation, Data Binding, and Type Conversion</title>
<section id="validation-introduction">
<section xml:id="validation-introduction">
<title>Introduction</title>
<para>There are pros and cons for considering validation as business logic,
@@ -45,7 +49,7 @@
chapter.</para>
</section>
<section id="validator">
<section xml:id="validator">
<title>Validation using Spring's <interfacename>Validator</interfacename>
interface</title>
@@ -92,7 +96,7 @@
<programlisting language="java"><![CDATA[public class PersonValidator implements Validator {
]]><lineannotation>/**
* This <interfacename>Validator</interfacename> validates <emphasis role="bold">just</emphasis> <classname>Person</classname> instances
* This Validator validates *just* Person instances
*/</lineannotation><![CDATA[
public boolean supports(Class clazz) {
return Person.class.equals(clazz);
@@ -152,7 +156,7 @@
}
]]><lineannotation>/**
* This <interfacename>Validator</interfacename> validates <classname>Customer</classname> instances, and any subclasses of <classname>Customer</classname> too
* This Validator validates Customer instances, and any subclasses of Customer too
*/</lineannotation><![CDATA[
public boolean supports(Class clazz) {
return Customer.class.isAssignableFrom(clazz);
@@ -179,7 +183,7 @@
be found from the Javadoc.</para>
</section>
<section id="validation-conversion">
<section xml:id="validation-conversion">
<title>Resolving codes to error messages</title>
<para>We've talked about databinding and validation. Outputting messages
@@ -210,14 +214,14 @@
<para>More information on the
<interfacename>MessageCodesResolver</interfacename> and the default
strategy can be found online with the Javadocs for <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/validation/MessageCodesResolver.html"
>MessageCodesResolver</ulink> and <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/validation/DefaultMessageCodesResolver.html"
>DefaultMessageCodesResolver</ulink> respectively.</para>
strategy can be found online with the Javadocs for <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/validation/MessageCodesResolver.html"
>MessageCodesResolver</link> and <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/validation/DefaultMessageCodesResolver.html"
>DefaultMessageCodesResolver</link> respectively.</para>
</section>
<section id="beans-beans">
<section xml:id="beans-beans">
<title>Bean manipulation and the
<interfacename>BeanWrapper</interfacename></title>
@@ -228,8 +232,8 @@
would have a setter method <methodname>setBingoMadness(..)</methodname>
and a getter method <methodname>getBingoMadness()</methodname>. For more
information about JavaBeans and the specification, please refer to Sun's
website ( <ulink url="http://java.sun.com/products/javabeans/"
>java.sun.com/products/javabeans</ulink>).</para>
website ( <link xl:href="http://java.sun.com/products/javabeans/"
>java.sun.com/products/javabeans</link>).</para>
<para>One quite important class in the beans package is the
<interfacename>BeanWrapper</interfacename> interface and its corresponding
@@ -255,7 +259,7 @@
indicated by its name: <emphasis>it wraps a bean</emphasis> to perform
actions on that bean, like setting and retrieving properties.</para>
<section id="beans-beans-conventions">
<section xml:id="beans-beans-conventions">
<title>Setting and getting basic and nested properties</title>
<para>Setting and getting properties is done using the
@@ -266,7 +270,7 @@
are a couple of conventions for indicating properties of an object. A
couple of examples:</para>
<table id="beans-beans-conventions-properties-tbl">
<table xml:id="beans-beans-conventions-properties-tbl">
<title>Examples of properties</title>
<tgroup cols="2">
@@ -389,8 +393,8 @@ company.setPropertyValue("managingDirector", jim.getWrappedInstance());
Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]></programlisting>
</section>
<section id="beans-beans-conversion">
<title>Built-in <interface>PropertyEditor</interface>
<section xml:id="beans-beans-conversion">
<title>Built-in <interfacename>PropertyEditor</interfacename>
implementations</title>
<para>Spring uses the concept of <literal>PropertyEditors</literal> to
@@ -442,7 +446,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]></
configurable in some fashion, you can of course still register your own
variant to override the default one:</para>
<table id="beans-beans-property-editors-tbl">
<table xml:id="beans-beans-property-editors-tbl">
<title>Built-in <literal>PropertyEditors</literal></title>
<tgroup cols="2">
@@ -598,13 +602,13 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]></
chank
pop
Foo
FooEditor ]]><lineannotation>// the <interfacename>PropertyEditor</interfacename> for the <classname>Foo</classname> class</lineannotation></programlisting>
FooEditor ]]><lineannotation>// the PropertyEditor for the Foo class</lineannotation></programlisting>
<para>Note that you can also use the standard
<interfacename>BeanInfo</interfacename> JavaBeans mechanism here as well
(described <ulink
url="http://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html"
>in not-amazing-detail here</ulink>). Find below an example of using the
(described <link
xl:href="http://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html"
>in not-amazing-detail here</link>). Find below an example of using the
<interfacename>BeanInfo</interfacename> mechanism for explicitly
registering one or more <interfacename>PropertyEditor</interfacename>
instances with the properties of an associated class.</para>
@@ -612,7 +616,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]></
chank
pop
Foo
FooBeanInfo ]]><lineannotation>// the <interfacename>BeanInfo</interfacename> for the <classname>Foo</classname> class</lineannotation></programlisting>
FooBeanInfo ]]><lineannotation>// the BeanInfo for the Foo class</lineannotation></programlisting>
<para> Here is the Java source code for the referenced
<classname>FooBeanInfo</classname> class. This would associate a
@@ -637,7 +641,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]></
}
}]]></programlisting>
<section id="beans-beans-conversion-customeditor-registration">
<section xml:id="beans-beans-conversion-customeditor-registration">
<title>Registering additional custom
<interfacename>PropertyEditors</interfacename></title>
@@ -725,7 +729,7 @@ public class DependsOnExoticType {
<para>The <interfacename>PropertyEditor</interfacename> implementation
could look similar to this:</para>
<programlisting language="java"><lineannotation>// converts string representation to <classname>ExoticType</classname> object</lineannotation><![CDATA[
<programlisting language="java"><lineannotation>// converts string representation to ExoticType object</lineannotation><![CDATA[
package example;
public class ExoticTypeEditor extends PropertyEditorSupport {
@@ -748,7 +752,7 @@ public class ExoticTypeEditor extends PropertyEditorSupport {
</property>
</bean>]]></programlisting>
<section id="beans-beans-conversion-customeditor-registration-per">
<section xml:id="beans-beans-conversion-customeditor-registration-per">
<title>Using
<interfacename>PropertyEditorRegistrars</interfacename></title>
@@ -791,7 +795,7 @@ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegist
public void registerCustomEditors(PropertyEditorRegistry registry) {
]]><lineannotation>// it is expected that new <interfacename>PropertyEditor</interfacename> instances are created</lineannotation><![CDATA[
]]><lineannotation>// it is expected that new PropertyEditor instances are created</lineannotation><![CDATA[
registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
]]><lineannotation>// you could register as many custom property editors as are required here...</lineannotation><![CDATA[
@@ -846,7 +850,7 @@ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegist
]]><emphasis role="bold">this.customPropertyEditorRegistrar.registerCustomEditors(binder);</emphasis><![CDATA[
}
]]><lineannotation>// other methods to do with registering a <classname>User</classname></lineannotation><![CDATA[
]]><lineannotation>// other methods to do with registering a User</lineannotation><![CDATA[
}]]></programlisting>
<para>This style of <interfacename>PropertyEditor</interfacename>
@@ -861,7 +865,7 @@ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegist
</section>
</section>
<section id="core-convert">
<section xml:id="core-convert">
<title>Spring 3 Type Conversion</title>
<para> Spring 3 introduces a <filename>core.convert</filename> package that
@@ -872,7 +876,7 @@ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegist
value strings to required property types. The public API may also be used
anywhere in your application where type conversion is needed. </para>
<section id="core-convert-Converter-API">
<section xml:id="core-convert-Converter-API">
<title>Converter SPI</title>
<para> The SPI to implement type conversion logic is simple and strongly
@@ -911,7 +915,7 @@ final class StringToInteger implements Converter<String, Integer> {
}]]></programlisting>
</section>
<section id="core-convert-ConverterFactory-SPI">
<section xml:id="core-convert-ConverterFactory-SPI">
<title>ConverterFactory</title>
<para> When you need to centralize the conversion logic for an entire
@@ -958,7 +962,7 @@ final class StringToEnumConverterFactory implements ConverterFactory<String, Enu
}]]></programlisting>
</section>
<section id="core-convert-GenericConverter-SPI">
<section xml:id="core-convert-GenericConverter-SPI">
<title>GenericConverter</title>
<para> When you require a sophisticated Converter implementation, consider
@@ -1001,7 +1005,7 @@ public interface GenericConverter {
type conversion needs. </para>
</note>
<section id="core-convert-ConditionalGenericConverter-SPI">
<section xml:id="core-convert-ConditionalGenericConverter-SPI">
<title>ConditionalGenericConverter</title>
<para> Sometimes you only want a Converter to execute if a specific
@@ -1027,7 +1031,7 @@ public interface GenericConverter {
</section>
</section>
<section id="core-convert-ConversionService-API">
<section xml:id="core-convert-ConversionService-API">
<title>ConversionService API</title>
<para> The ConversionService defines a unified API for executing type
@@ -1049,7 +1053,7 @@ public interface ConversionService {
}]]></programlisting>
<para> Most ConversionService implementations also implement
<interface>ConverterRegistry</interface>, which provides an SPI for
<interfacename>ConverterRegistry</interfacename>, which provides an SPI for
registering converters. Internally, a ConversionService implementation
delegates to its registered converters to carry out type conversion
logic. </para>
@@ -1062,7 +1066,7 @@ public interface ConversionService {
factory for creating common ConversionService configurations. </para>
</section>
<section id="core-convert-Spring-config">
<section xml:id="core-convert-Spring-config">
<title>Configuring a ConversionService</title>
<para> A ConversionService is a stateless object designed to be
@@ -1110,7 +1114,7 @@ public interface ConversionService {
<classname>FormattingConversionServiceFactoryBean</classname>.</para>
</section>
<section id="core-convert-programmatic-usage">
<section xml:id="core-convert-programmatic-usage">
<title>Using a ConversionService programmatically</title>
<para> To work with a ConversionService instance programmatically, simply
@@ -1131,7 +1135,7 @@ public class MyService {
</section>
</section>
<section id="format">
<section xml:id="format">
<title>Spring 3 Field Formatting</title>
<para> As discussed in the previous section, <link linkend="core-convert"
@@ -1164,7 +1168,7 @@ public class MyService {
parse and print localized field values. The ConversionService provides a
unified type conversion API for both SPIs. </para>
<section id="format-Formatter-SPI">
<section xml:id="format-Formatter-SPI">
<title>Formatter SPI</title>
<para> The Formatter SPI to implement field formatting logic is simple and
@@ -1207,8 +1211,8 @@ public interface Parser<T> {
<filename>datetime</filename> package provides a DateFormatter to format
java.util.Date objects with a java.text.DateFormat. The
<filename>datetime.joda</filename> package provides comprehensive
datetime formatting support based on the <ulink
url="http://joda-time.sourceforge.net">Joda Time library</ulink>. </para>
datetime formatting support based on the <link
xl:href="http://joda-time.sourceforge.net">Joda Time library</link>. </para>
<para> Consider <classname>DateFormatter</classname> as an example
<interfacename>Formatter</interfacename> implementation: </para>
@@ -1246,11 +1250,11 @@ public final class DateFormatter implements Formatter<Date> {
}]]></programlisting>
<para> The Spring team welcomes community-driven Formatter contributions;
see <ulink url="http://jira.springframework.org"
>http://jira.springframework.org</ulink> to contribute. </para>
see <link xl:href="http://jira.springframework.org"
>http://jira.springframework.org</link> to contribute. </para>
</section>
<section id="format-CustomFormatAnnotations">
<section xml:id="format-CustomFormatAnnotations">
<title>Annotation-driven Formatting</title>
<para> As you will see, field formatting can be configured by field type
@@ -1325,7 +1329,7 @@ public interface AnnotationFormatterFactory<A extends Annotation> {
}]]></programlisting>
<section id="format-annotations-api">
<section xml:id="format-annotations-api">
<title>Format Annotation API</title>
<para> A portable format annotation API exists in the
@@ -1346,18 +1350,18 @@ public interface AnnotationFormatterFactory<A extends Annotation> {
</section>
</section>
<section id="format-FormatterRegistry-SPI">
<section xml:id="format-FormatterRegistry-SPI">
<title>FormatterRegistry SPI</title>
<para> The FormatterRegistry is an SPI for registering formatters and
converters. <classname>FormattingConversionService</classname> is
an implementation of FormatterRegistry suitable for most environments.
This implementation may be configured programmatically or declaratively
as a Spring bean using
<classname>FormattingConversionServiceFactoryBean</classname>.
Because this implementation also implements
<classname>ConversionService</classname>, it can be directly
configured for use with Spring's DataBinder and the Spring Expression
<para> The FormatterRegistry is an SPI for registering formatters and
converters. <classname>FormattingConversionService</classname> is
an implementation of FormatterRegistry suitable for most environments.
This implementation may be configured programmatically or declaratively
as a Spring bean using
<classname>FormattingConversionServiceFactoryBean</classname>.
Because this implementation also implements
<classname>ConversionService</classname>, it can be directly
configured for use with Spring's DataBinder and the Spring Expression
Language (SpEL).
</para>
@@ -1378,24 +1382,24 @@ public interface FormatterRegistry extends ConverterRegistry {
}]]></programlisting>
<para> As shown above, Formatters can be registered by fieldType or
annotation.
annotation.
</para>
<para> The FormatterRegistry SPI allows you to configure Formatting rules
centrally, instead of duplicating such configuration across your
Controllers. For example, you might want to enforce that all Date fields
are formatted a certain way, or fields with a specific annotation are
formatted in a certain way. With a shared FormatterRegistry, you define
these rules once and they are applied whenever formatting is needed.
</para>
these rules once and they are applied whenever formatting is needed.
</para>
</section>
<section id="format-FormatterRegistrar-SPI">
<section xml:id="format-FormatterRegistrar-SPI">
<title>FormatterRegistrar SPI</title>
<para> The FormatterRegistrar is an SPI for registering formatters and
converters through the FormatterRegistry:
</para>
<para> The FormatterRegistrar is an SPI for registering formatters and
converters through the FormatterRegistry:
</para>
<programlisting language="java"><![CDATA[package org.springframework.format;
public interface FormatterRegistrar {
@@ -1404,17 +1408,17 @@ public interface FormatterRegistrar {
}]]></programlisting>
<para> A FormatterRegistrar is useful when registering multiple related
converters and formatters for a given formatting category, such as Date
formatting. It can also be useful where declarative registration is
insufficient. For example when a formatter needs to be indexed under a
specific field type different from its own &lt;T&gt; or when registering
a Printer/Parser pair. The next section provides more information on
converter and formatter registration.
</para>
</section>
<section id="format-configuring-formatting-mvc">
<para> A FormatterRegistrar is useful when registering multiple related
converters and formatters for a given formatting category, such as Date
formatting. It can also be useful where declarative registration is
insufficient. For example when a formatter needs to be indexed under a
specific field type different from its own &lt;T&gt; or when registering
a Printer/Parser pair. The next section provides more information on
converter and formatter registration.
</para>
</section>
<section xml:id="format-configuring-formatting-mvc">
<title>Configuring Formatting in Spring MVC</title>
<para> In a Spring MVC application, you may configure a custom
@@ -1449,7 +1453,7 @@ public interface FormatterRegistrar {
classpath.</para>
<para> To inject a ConversionService instance with custom formatters and
converters registered, set the conversion-service attribute and then
converters registered, set the conversion-service attribute and then
specify custom converters, formatters, or FormatterRegistrars as properties
of the FormattingConversionServiceFactoryBean: </para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
@@ -1487,16 +1491,16 @@ public interface FormatterRegistrar {
</beans>]]></programlisting>
<note>
<para> See <xref linkend="format-FormatterRegistrar-SPI"/> and
the <classname>FormattingConversionServiceFactoryBean</classname>
for more information on when to use FormatterRegistrars.
</para>
<para> See <xref linkend="format-FormatterRegistrar-SPI"/> and
the <classname>FormattingConversionServiceFactoryBean</classname>
for more information on when to use FormatterRegistrars.
</para>
</note>
</section>
</section>
<section id="format-configuring-formatting-globaldatetimeformat">
<section xml:id="format-configuring-formatting-globaldatetimeformat">
<title>Configuring a global date &amp; time format</title>
<para>By default, date and time fields that are not annotated with
@@ -1586,7 +1590,7 @@ public class AppConfig {
<xref linkend="format-configuring-formatting-mvc"/> for details.</para>
</section>
<section id="validation-beanvalidation">
<section xml:id="validation-beanvalidation">
<title>Spring 3 Validation</title>
<para> Spring 3 introduces several enhancements to its validation support.
@@ -1595,7 +1599,7 @@ public class AppConfig {
well as bind to them. Third, Spring MVC now has support for declaratively
validating @Controller inputs. </para>
<section id="validation-beanvalidation-overview">
<section xml:id="validation-beanvalidation-overview">
<title>Overview of the JSR-303 Bean Validation API</title>
<para> JSR-303 standardizes validation constraint declaration and metadata
@@ -1629,16 +1633,16 @@ public class AppConfig {
<para> When an instance of this class is validated by a JSR-303 Validator,
these constraints will be enforced. </para>
<para> For general information on JSR-303, see the <ulink
url="http://jcp.org/en/jsr/detail?id=303">Bean Validation
Specification</ulink>. For information on the specific capabilities of
the default reference implementation, see the <ulink
url="https://www.hibernate.org/412.html">Hibernate Validator</ulink>
<para> For general information on JSR-303, see the <link
xl:href="http://jcp.org/en/jsr/detail?id=303">Bean Validation
Specification</link>. For information on the specific capabilities of
the default reference implementation, see the <link
xl:href="https://www.hibernate.org/412.html">Hibernate Validator</link>
documentation. To learn how to setup a JSR-303 implementation as a
Spring bean, keep reading. </para>
</section>
<section id="validation-beanvalidation-spring">
<section xml:id="validation-beanvalidation-spring">
<title>Configuring a Bean Validation Implementation</title>
<para> Spring provides full support for the JSR-303 Bean Validation API.
@@ -1659,7 +1663,7 @@ public class AppConfig {
Hibernate Validator, is expected to be present in the classpath and will
be detected automatically. </para>
<section id="validation-beanvalidation-spring-inject">
<section xml:id="validation-beanvalidation-spring-inject">
<title>Injecting a Validator</title>
<para> <classname>LocalValidatorFactoryBean</classname> implements both
@@ -1695,7 +1699,7 @@ public class MyService {
}]]></programlisting>
</section>
<section id="validation-beanvalidation-spring-constraints">
<section xml:id="validation-beanvalidation-spring-constraints">
<title>Configuring Custom Constraints</title>
<para> Each JSR-303 validation constraint consists of two parts. First,
@@ -1739,7 +1743,7 @@ public class MyConstraintValidator implements ConstraintValidator {
dependencies @Autowired like any other Spring bean. </para>
</section>
<section id="validation-beanvalidation-spring-other">
<section xml:id="validation-beanvalidation-spring-other">
<title>Additional Configuration Options</title>
<para> The default <classname>LocalValidatorFactoryBean</classname>
@@ -1751,7 +1755,7 @@ public class MyConstraintValidator implements ConstraintValidator {
</section>
</section>
<section id="validation-binder">
<section xml:id="validation-binder">
<title>Configuring a DataBinder</title>
<para> Since Spring 3, a DataBinder instance can be configured with a
@@ -1776,14 +1780,14 @@ binder.validate();
BindingResult results = binder.getBindingResult();</programlisting>
</section>
<section id="validation-mvc">
<section xml:id="validation-mvc">
<title>Spring MVC 3 Validation</title>
<para> Beginning with Spring 3, Spring MVC has the ability to
automatically validate @Controller inputs. In previous versions it was
up to the developer to manually invoke validation logic. </para>
<section id="validation-mvc-triggering">
<section xml:id="validation-mvc-triggering">
<title>Triggering @Controller Input Validation</title>
<para> To trigger validation of a @Controller input, simply annotate the
@@ -1803,7 +1807,7 @@ public class MyController {
</note>
</section>
<section id="validation-mvc-configuring">
<section xml:id="validation-mvc-configuring">
<title>Configuring a Validator for use by Spring MVC</title>
<para> The Validator instance invoked when a @Valid method argument is
@@ -1845,7 +1849,7 @@ public class MyController {
</beans>]]></programlisting>
</section>
<section id="validation-mvc-jsr303">
<section xml:id="validation-mvc-jsr303">
<title>Configuring a JSR-303 Validator for use by Spring MVC</title>
<para> With JSR-303, a single <code>javax.validation.Validator</code>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="view"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="view">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>View technologies</title>
<section id="view-introduction">
<section xml:id="view-introduction">
<title>Introduction</title>
<para>One of the areas in which Spring excels is in the separation of view
@@ -18,7 +22,7 @@
framework.</para>
</section>
<section id="view-jsp">
<section xml:id="view-jsp">
<title>JSP &amp; JSTL</title>
<para>Spring provides a couple of out-of-the-box solutions for JSP and
@@ -26,22 +30,22 @@
in the <interfacename>WebApplicationContext</interfacename>. Furthermore,
of course you need to write some JSPs that will actually render the
view.</para>
<note>
<para>
Setting up your application to use JSTL is a common source of error,
mainly caused by confusion over the different servlet spec., JSP and JSTL
version numbers, what they mean and how to declare the taglibs correctly.
version numbers, what they mean and how to declare the taglibs correctly.
The article
<ulink url="http://www.mularien.com/blog/2008/04/24/how-to-reference-and-use-jstl-in-your-web-application/">
How to Reference and Use JSTL in your Web Application</ulink> provides a
<link xl:href="http://www.mularien.com/blog/2008/04/24/how-to-reference-and-use-jstl-in-your-web-application/">
How to Reference and Use JSTL in your Web Application</link> provides a
useful guide to the common pitfalls and how to avoid them. Note that as of
Spring 3.0, the minimum supported servlet version is 2.4 (JSP 2.0 and JSTL 1.1),
which reduces the scope for confusion somewhat.
</para>
</note>
<section id="view-jsp-resolver">
<section xml:id="view-jsp-resolver">
<title>View resolvers</title>
<para>Just as with any other view technology you're integrating with
@@ -51,7 +55,7 @@
<classname>ResourceBundleViewResolver</classname>. Both are declared in
the <interfacename>WebApplicationContext</interfacename>:</para>
<programlisting language="xml"><lineannotation>&lt;!-- the <classname>ResourceBundleViewResolver</classname> --&gt;</lineannotation>
<programlisting language="xml"><lineannotation>&lt;!-- the ResourceBundleViewResolver --&gt;</lineannotation>
&lt;bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"&gt;
&lt;property name="basename" value="views"/&gt;
&lt;/bean&gt;
@@ -82,7 +86,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
be no direct access by clients.</para>
</section>
<section id="view-jsp-jstl">
<section xml:id="view-jsp-jstl">
<title>'Plain-old' JSPs versus JSTL</title>
<para>When using the Java Standard Tag Library you must use a special
@@ -90,7 +94,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
preparation before things such as the I18N features will work.</para>
</section>
<section id="view-jsp-tags">
<section xml:id="view-jsp-tags">
<title>Additional tags facilitating development</title>
<para>Spring provides data binding of request parameters to command
@@ -106,7 +110,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
the appendix entitled <xref linkend="spring.tld" />.</para>
</section>
<section id="view-jsp-formtaglib">
<section xml:id="view-jsp-formtaglib">
<title>Using Spring's form tag library</title>
<para>As of version 2.0, Spring provides a comprehensive set of data
@@ -126,7 +130,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
tag is used. We have included generated HTML snippets where certain tags
require further commentary.</para>
<section id="view-jsp-formtaglib-configuration">
<section xml:id="view-jsp-formtaglib-configuration">
<title>Configuration</title>
<para>The form tag library comes bundled in
@@ -143,7 +147,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
want to use for the tags from this library.</para>
</section>
<section id="view-jsp-formtaglib-formtag">
<section xml:id="view-jsp-formtaglib-formtag">
<title>The <literal>form</literal> tag</title>
<para>This tag renders an HTML 'form' tag and exposes a binding path
@@ -228,17 +232,17 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/form:form&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-inputtag">
<section xml:id="view-jsp-formtaglib-inputtag">
<title>The <literal>input</literal> tag</title>
<para>This tag renders an HTML 'input' tag using the bound value
and type='text' by default. For an example of this tag, see <xref
linkend="view-jsp-formtaglib-formtag" />. Starting with Spring 3.1
you can use other types such HTML5-specific types like 'email',
you can use other types such HTML5-specific types like 'email',
'tel', 'date', and others.</para>
</section>
<section id="view-jsp-formtaglib-checkboxtag">
<section xml:id="view-jsp-formtaglib-checkboxtag">
<title>The <literal>checkbox</literal> tag</title>
<para>This tag renders an HTML 'input' tag with type
@@ -287,14 +291,14 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;Subscribe to newsletter?:&lt;/td&gt;
<lineannotation>&lt;%-- Approach 1: Property is of type <classname>java.lang.Boolean</classname> --%&gt;</lineannotation>
<lineannotation>&lt;%-- Approach 1: Property is of type java.lang.Boolean --%&gt;</lineannotation>
&lt;td&gt;&lt;form:checkbox path="preferences.receiveNewsletter"/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interests:&lt;/td&gt;
&lt;td&gt;
<lineannotation>&lt;%-- Approach 2: Property is of an array or of type <interfacename>java.util.Collection</interfacename> --%&gt;</lineannotation>
<lineannotation>&lt;%-- Approach 2: Property is of an array or of type java.util.Collection --%&gt;</lineannotation>
Quidditch: &lt;form:checkbox path="preferences.interests" value="Quidditch"/&gt;
Herbology: &lt;form:checkbox path="preferences.interests" value="Herbology"/&gt;
Defence Against the Dark Arts: &lt;form:checkbox path="preferences.interests"
@@ -304,7 +308,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;tr&gt;
&lt;td&gt;Favourite Word:&lt;/td&gt;
&lt;td&gt;
<lineannotation>&lt;%-- Approach 3: Property is of type <classname>java.lang.Object</classname> --%&gt;</lineannotation>
<lineannotation>&lt;%-- Approach 3: Property is of type java.lang.Object --%&gt;</lineannotation>
Magic: &lt;form:checkbox path="preferences.favouriteWord" value="Magic"/&gt;
&lt;/td&gt;
&lt;/tr&gt;
@@ -313,7 +317,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
<para>There are 3 approaches to the <literal>checkbox</literal> tag
which should meet all your checkbox needs.</para>
<itemizedlist>
<listitem>
<para>Approach One - When the bound value is of type
@@ -373,7 +377,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
</quote>.</para>
</section>
<section id="view-jsp-formtaglib-checkboxestag">
<section xml:id="view-jsp-formtaglib-checkboxestag">
<title>The <literal>checkboxes</literal> tag</title>
<para>This tag renders multiple HTML 'input' tags with type
@@ -396,7 +400,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;tr&gt;
&lt;td&gt;Interests:&lt;/td&gt;
&lt;td&gt;
<lineannotation>&lt;%-- Property is of an array or of type <interfacename>java.util.Collection</interfacename> --%&gt;</lineannotation>
<lineannotation>&lt;%-- Property is of an array or of type java.util.Collection --%&gt;</lineannotation>
&lt;form:checkboxes path="preferences.interests" items="${interestList}"/&gt;
&lt;/td&gt;
&lt;/tr&gt;
@@ -412,7 +416,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
using "itemValue" and the label using "itemLabel".</para>
</section>
<section id="view-jsp-formtaglib-radiobuttontag">
<section xml:id="view-jsp-formtaglib-radiobuttontag">
<title>The <literal>radiobutton</literal> tag</title>
<para>This tag renders an HTML 'input' tag with type 'radio'.</para>
@@ -427,7 +431,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/tr&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-radiobuttonstag">
<section xml:id="view-jsp-formtaglib-radiobuttonstag">
<title>The <literal>radiobuttons</literal> tag</title>
<para>This tag renders multiple HTML 'input' tags with type
@@ -450,7 +454,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/tr&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-passwordtag">
<section xml:id="view-jsp-formtaglib-passwordtag">
<title>The <literal>password</literal> tag</title>
<para>This tag renders an HTML 'input' tag with type 'password' using
@@ -476,7 +480,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/tr&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-selecttag">
<section xml:id="view-jsp-formtaglib-selecttag">
<title>The <literal>select</literal> tag</title>
<para>This tag renders an HTML 'select' element. It supports data
@@ -504,7 +508,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/tr&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-optiontag">
<section xml:id="view-jsp-formtaglib-optiontag">
<title>The <literal>option</literal> tag</title>
<para>This tag renders an HTML 'option'. It sets 'selected' as
@@ -538,7 +542,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/tr&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-optionstag">
<section xml:id="view-jsp-formtaglib-optionstag">
<title>The <literal>options</literal> tag</title>
<para>This tag renders a list of HTML 'option' tags. It sets the
@@ -588,7 +592,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
property will apply to the map value.</para>
</section>
<section id="view-jsp-formtaglib-textAreatag">
<section xml:id="view-jsp-formtaglib-textAreatag">
<title>The <literal>textarea</literal> tag</title>
<para>This tag renders an HTML 'textarea'.</para>
@@ -600,7 +604,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/tr&gt;</programlisting>
</section>
<section id="view-jsp-formtaglib-hiddeninputtag">
<section xml:id="view-jsp-formtaglib-hiddeninputtag">
<title>The <literal>hidden</literal> tag</title>
<para>This tag renders an HTML 'input' tag with type 'hidden' using
@@ -617,7 +621,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
</programlisting>
</section>
<section id="view-jsp-formtaglib-errorstag">
<section xml:id="view-jsp-formtaglib-errorstag">
<title>The <literal>errors</literal> tag</title>
<para>This tag renders field errors in an HTML 'span' tag. It provides
@@ -761,7 +765,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
&lt;/form&gt;</programlisting>
</section>
<section id="rest-method-conversion">
<section xml:id="rest-method-conversion">
<title>HTTP Method Conversion</title>
<para>A key principle of REST is the use of the Uniform Interface.
@@ -812,25 +816,25 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
}</programlisting>
</section>
<section id="view-jsp-formtaglib-html5">
<section xml:id="view-jsp-formtaglib-html5">
<title>HTML5 Tags</title>
<para>Starting with Spring 3, the Spring form tag library allows entering
dynamic attributes, which means you can enter any HTML5 specific attributes.
</para>
dynamic attributes, which means you can enter any HTML5 specific attributes.
</para>
<para>In Spring 3.1, the form input tag supports entering a type attribute
other than 'text'. This is intended to allow rendering new HTML5 specific
input types such as 'email', 'date', 'range', and others. Note that
entering type='text' is not required since 'text' is the default type.
</para>
other than 'text'. This is intended to allow rendering new HTML5 specific
input types such as 'email', 'date', 'range', and others. Note that
entering type='text' is not required since 'text' is the default type.
</para>
</section>
</section>
</section>
<section id="view-tiles">
<section xml:id="view-tiles">
<title>Tiles</title>
<para>It is possible to integrate Tiles - just as any other view
@@ -847,7 +851,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
<literal>org.springframework.web.servlet.view.tiles</literal>
package.</para>
<section id="view-tiles-dependencies">
<section xml:id="view-tiles-dependencies">
<title>Dependencies</title>
<para>To be able to use Tiles you have to have a couple of additional
@@ -874,13 +878,13 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
</section>
<section id="view-tiles-integrate">
<section xml:id="view-tiles-integrate">
<title>How to integrate Tiles</title>
<para>To be able to use Tiles, you have to configure it using files
containing definitions (for basic information on definitions and other
Tiles concepts, please have a look at <ulink
url="http://tiles.apache.org" />). In Spring this is done using the
Tiles concepts, please have a look at <link
xl:href="http://tiles.apache.org" />). In Spring this is done using the
<classname>TilesConfigurer</classname>. Have a look at the following
piece of example ApplicationContext configuration:</para>
@@ -908,7 +912,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
find two possibilities, the <classname>UrlBasedViewResolver</classname>
and the <classname>ResourceBundleViewResolver</classname>.</para>
<section id="view-tiles-url">
<section xml:id="view-tiles-url">
<title>
<classname>UrlBasedViewResolver</classname>
</title>
@@ -922,7 +926,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
&lt;/bean&gt;</programlisting>
</section>
<section id="view-tiles-resource">
<section xml:id="view-tiles-resource">
<title>
<classname>ResourceBundleViewResolver</classname>
</title>
@@ -950,13 +954,13 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
<classname>ResourceBundleViewResolver</classname>, you can easily mix
different view technologies.</para>
<para>Note that the <classname>TilesView</classname> class for Tiles 2
supports JSTL (the JSP Standard Tag Library) out of the box, whereas
there is a separate <classname>TilesJstlView</classname> subclass in the
Tiles 1.x support.</para>
<para>Note that the <classname>TilesView</classname> class for Tiles 2
supports JSTL (the JSP Standard Tag Library) out of the box, whereas
there is a separate <classname>TilesJstlView</classname> subclass in the
Tiles 1.x support.</para>
</section>
<section id="view-tiles-preparer">
<section xml:id="view-tiles-preparer">
<title><classname>SimpleSpringPreparerFactory</classname> and
<classname>SpringBeanPreparerFactory</classname></title>
@@ -1005,18 +1009,18 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
</section>
</section>
<section id="view-velocity">
<section xml:id="view-velocity">
<title>Velocity &amp; FreeMarker</title>
<para><ulink url="http://velocity.apache.org">Velocity</ulink> and <ulink
url="http://www.freemarker.org">FreeMarker</ulink> are two templating
<para><link xl:href="http://velocity.apache.org">Velocity</link> and <link
xl:href="http://www.freemarker.org">FreeMarker</link> are two templating
languages that can be used as view technologies within Spring MVC
applications. The languages are quite similar and serve similar needs and
so are considered together in this section. For semantic and syntactic
differences between the two languages, see the <ulink
url="http://www.freemarker.org">FreeMarker</ulink> web site.</para>
differences between the two languages, see the <link
xl:href="http://www.freemarker.org">FreeMarker</link> web site.</para>
<section id="view-velocity-dependencies">
<section xml:id="view-velocity-dependencies">
<title>Dependencies</title>
<para>Your web application will need to include <filename
@@ -1035,14 +1039,14 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
class="libraryfile">velocity-tools-generic-1.x.jar</filename></para>
</section>
<section id="view-velocity-contextconfig">
<section xml:id="view-velocity-contextconfig">
<title>Context configuration</title>
<para>A suitable configuration is initialized by adding the relevant
configurer bean definition to your <filename>'*-servlet.xml'</filename>
as shown below:</para>
<programlisting language="xml"><lineannotation>&lt;!--
<programlisting language="xml"><lineannotation>&lt;!--
This bean sets up the Velocity environment for us based on a root path for templates.
Optionally, a properties file can be specified for more control over the Velocity
environment, but the defaults are pretty sane for file based template loading.
@@ -1051,7 +1055,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
&lt;property name="resourceLoaderPath" value="/WEB-INF/velocity/"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!--
<lineannotation>&lt;!--
View resolvers can also be configured with ResourceBundles or XML files. If you need
different view resolving based on Locale, you have to use the resource bundle resolver.
@@ -1068,7 +1072,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
&lt;property name="templateLoaderPath" value="/WEB-INF/freemarker/"/&gt;
&lt;/bean&gt;
<lineannotation>&lt;!--
<lineannotation>&lt;!--
View resolvers can also be configured with ResourceBundles or XML files. If you need
different view resolving based on Locale, you have to use the resource bundle resolver.
@@ -1088,7 +1092,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
</note>
</section>
<section id="view-velocity-createtemplates">
<section xml:id="view-velocity-createtemplates">
<title>Creating templates</title>
<para>Your templates need to be stored in the directory specified by the
@@ -1105,14 +1109,14 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
appropriate.</para>
</section>
<section id="view-velocity-advancedconfig">
<section xml:id="view-velocity-advancedconfig">
<title>Advanced configuration</title>
<para>The basic configurations highlighted above will be suitable for
most application requirements, however additional configuration options
are available for when unusual or advanced requirements dictate.</para>
<section id="view-velocity-example-velocityproperties">
<section xml:id="view-velocity-example-velocityproperties">
<title>velocity.properties</title>
<para>This file is completely optional, but if specified, contains the
@@ -1142,14 +1146,14 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>Refer to the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/ui/velocity/VelocityEngineFactory.html">API
documentation</ulink> for Spring configuration of Velocity, or the
<para>Refer to the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/ui/velocity/VelocityEngineFactory.html">API
documentation</link> for Spring configuration of Velocity, or the
Velocity documentation for examples and definitions of the
<filename>'velocity.properties'</filename> file itself.</para>
</section>
<section id="views-freemarker">
<section xml:id="views-freemarker">
<title>FreeMarker</title>
<para>FreeMarker 'Settings' and 'SharedVariables' can be passed
@@ -1178,7 +1182,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
</section>
</section>
<section id="view-velocity-forms">
<section xml:id="view-velocity-forms">
<title>Bind support and form handling</title>
<para>Spring provides a tag library for use in JSP's that contains
@@ -1190,7 +1194,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
and FreeMarker, with additional convenience macros for generating form
input elements themselves.</para>
<section id="view-bind-macros">
<section xml:id="view-bind-macros">
<title>The bind macros</title>
<para>A standard set of macros are maintained within the
@@ -1209,7 +1213,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
respectively.</para>
</section>
<section id="view-simple-binding">
<section xml:id="view-simple-binding">
<title>Simple binding</title>
<para>In your html forms (vm / ftl templates) that act as the
@@ -1226,14 +1230,14 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
&lt;html&gt;
...
&lt;form action="" method="POST"&gt;
Name:
Name:
#springBind( "command.name" )
&lt;input type="text"
name="${status.expression}"
&lt;input type="text"
name="${status.expression}"
value="$!status.value" /&gt;&lt;br&gt;
#foreach($error in $status.errorMessages) &lt;b&gt;$error&lt;/b&gt; &lt;br&gt; #end
&lt;br&gt;
...
...
&lt;input type="submit" value="submit"/&gt;
&lt;/form&gt;
...
@@ -1245,14 +1249,14 @@ recommend sticking to 'spring' --&gt;
&lt;html&gt;
...
&lt;form action="" method="POST"&gt;
Name:
&lt;@spring.bind "command.name" /&gt;
&lt;input type="text"
name="${spring.status.expression}"
Name:
&lt;@spring.bind "command.name" /&gt;
&lt;input type="text"
name="${spring.status.expression}"
value="${spring.status.value?default("")}" /&gt;&lt;br&gt;
&lt;#list spring.status.errorMessages as error&gt; &lt;b&gt;${error}&lt;/b&gt; &lt;br&gt; &lt;/#list&gt;
&lt;br&gt;
...
...
&lt;input type="submit" value="submit"/&gt;
&lt;/form&gt;
...
@@ -1278,7 +1282,7 @@ recommend sticking to 'spring' --&gt;
the next section.</para>
</section>
<section id="views-form-macros">
<section xml:id="views-form-macros">
<title>Form input generation macros</title>
<para>Additional convenience macros for both languages simplify both
@@ -1290,7 +1294,7 @@ recommend sticking to 'spring' --&gt;
<para>The following table of available macros show the VTL and FTL
definitions and the parameter list that each takes.</para>
<table id="views-macros-defs-tbl">
<table xml:id="views-macros-defs-tbl">
<title>Table of macro definitions</title>
<tgroup cols="3">
@@ -1515,7 +1519,7 @@ recommend sticking to 'spring' --&gt;
in VTL. Where usage differences exist between the two languages, they
are explained in the notes.</para>
<section id="views-form-macros-input">
<section xml:id="views-form-macros-input">
<title>Input Fields</title>
<para><programlisting language="xml">&lt;!-- the Name field example from above using form macros in VTL --&gt;
@@ -1550,7 +1554,7 @@ recommend sticking to 'spring' --&gt;
<para>The generated HTML looks like this:</para>
<programlisting>Name:
&lt;input type="text" name="name" value=""
&lt;input type="text" name="name" value=""
&gt;
&lt;br&gt;
&lt;b&gt;required&lt;/b&gt;
@@ -1563,7 +1567,7 @@ recommend sticking to 'spring' --&gt;
rows and cols attributes for the textarea.</para>
</section>
<section id="views-form-macros-select">
<section xml:id="views-form-macros-select">
<title>Selection Fields</title>
<para>Four selection field macros can be used to generate common UI
@@ -1613,15 +1617,15 @@ recommend sticking to 'spring' --&gt;
<programlisting>Town:
&lt;input type="radio" name="address.town" value="London"
&gt;
London
&lt;input type="radio" name="address.town" value="Paris"
checked="checked"
checked="checked"
&gt;
Paris
&lt;input type="radio" name="address.town" value="New York"
&gt;
New York</programlisting>
@@ -1634,7 +1638,7 @@ New York</programlisting>
cityMap.put("LDN", "London");
cityMap.put("PRS", "Paris");
cityMap.put("NYC", "New York");
Map m = new HashMap();
m.put("cityMap", cityMap);
return m;
@@ -1646,21 +1650,21 @@ New York</programlisting>
<programlisting>Town:
&lt;input type="radio" name="address.town" value="LDN"
&gt;
London
&lt;input type="radio" name="address.town" value="PRS"
checked="checked"
checked="checked"
&gt;
Paris
&lt;input type="radio" name="address.town" value="NYC"
&gt;
New York</programlisting>
</section>
</section>
<section id="views-form-macros-html-escaping">
<section xml:id="views-form-macros-html-escaping">
<title>HTML escaping and XHTML compliance</title>
<para>Default usage of the form macros above will result in HTML tags
@@ -1700,7 +1704,7 @@ New York</programlisting>
</section>
</section>
<section id="view-xslt">
<section xml:id="view-xslt">
<title>XSLT</title>
<para>XSLT is a transformation language for XML and is popular as a view
@@ -1710,7 +1714,7 @@ New York</programlisting>
an XML document as model data and have it transformed with XSLT in a
Spring Web MVC application.</para>
<section id="view-xslt-firstwords">
<section xml:id="view-xslt-firstwords">
<title>My First Words</title>
<para>This example is a trivial Spring application that creates a list
@@ -1721,7 +1725,7 @@ New York</programlisting>
turn the list of words into a simple XML document ready for
transformation.</para>
<section id="view-xslt-beandefs">
<section xml:id="view-xslt-beandefs">
<title>Bean definitions</title>
<para>Configuration is standard for a simple Spring application. The
@@ -1734,7 +1738,7 @@ New York</programlisting>
<para>... that encapsulates our word generation logic.</para>
</section>
<section id="view-xslt-controllercode">
<section xml:id="view-xslt-controllercode">
<title>Standard MVC controller code</title>
<para>The controller logic is encapsulated in a subclass of
@@ -1744,15 +1748,15 @@ New York</programlisting>
<programlisting language="java">protected ModelAndView handleRequestInternal(
HttpServletRequest request,
HttpServletResponse response) throws Exception {
Map map = new HashMap();
List wordList = new ArrayList();
wordList.add("hello");
wordList.add("world");
map.put("wordList", wordList);
return new ModelAndView("home", map);
}</programlisting>
@@ -1771,7 +1775,7 @@ New York</programlisting>
tools to manage the domification process.</para>
</section>
<section id="view-xslt-subclassing">
<section xml:id="view-xslt-subclassing">
<title>Convert the model data to XML</title>
<para>In order to create a DOM document from our list of words or any
@@ -1822,7 +1826,7 @@ public class HomePage extends AbstractXsltView {
request)</methodname> method instead.</para>
</section>
<section id="view-xslt-viewdefinitions">
<section xml:id="view-xslt-viewdefinitions">
<title>Defining the view properties</title>
<para>The views.properties file (or equivalent xml definition if
@@ -1845,7 +1849,7 @@ home.root=words</programlisting>
the <methodname>createXsltSource(..)</methodname> method(s).</para>
</section>
<section id="view-xslt-transforming">
<section xml:id="view-xslt-transforming">
<title>Document transformation</title>
<para>Finally, we have the XSLT code used for transforming the above
@@ -1877,7 +1881,7 @@ home.root=words</programlisting>
</section>
</section>
<section id="view-xslt-summary">
<section xml:id="view-xslt-summary">
<title>Summary</title>
<para>A summary of the files discussed and their location in the WAR
@@ -1893,7 +1897,7 @@ home.root=words</programlisting>
| |
| +- xslt
| | |
| | +- HomePageController.class
| | +- HomePageController.class
| | +- HomePage.class
| |
| +- views.properties
@@ -1915,10 +1919,10 @@ home.root=words</programlisting>
</section>
</section>
<section id="view-document">
<section xml:id="view-document">
<title>Document views (PDF/Excel)</title>
<section id="view-document-intro">
<section xml:id="view-document-intro">
<title>Introduction</title>
<para>Returning an HTML page isn't always the best way for the user to
@@ -1932,7 +1936,7 @@ home.root=words</programlisting>
your classpath, and for PDF generation, the iText library.</para>
</section>
<section id="view-document-config">
<section xml:id="view-document-config">
<title>Configuration and setup</title>
<para>Document based views are handled in an almost identical fashion to
@@ -1942,14 +1946,14 @@ home.root=words</programlisting>
spreadsheet (which can also be viewed or manipulated in Open
Office).</para>
<section id="view-document-configviews">
<section xml:id="view-document-configviews">
<title>Document view definitions</title>
<para>First, let's amend the views.properties file (or xml
equivalent) and add a simple view definition for both document types.
The entire file now looks like this with the XSLT view shown from
earlier:</para>
<programlisting>home.(class)=xslt.HomePage
home.stylesheetLocation=/WEB-INF/xsl/home.xslt
home.root=words
@@ -1963,7 +1967,7 @@ pdf.(class)=pdf.HomePage</programlisting>
as the 'url' property in the view definition</emphasis></para>
</section>
<section id="view-document-configcontroller">
<section xml:id="view-document-configcontroller">
<title>Controller code</title>
<para>The controller code we'll use remains exactly the same from the
@@ -1973,7 +1977,7 @@ pdf.(class)=pdf.HomePage</programlisting>
at decoupling the views from the controllers!</para>
</section>
<section id="view-document-configsubclasses">
<section xml:id="view-document-configsubclasses">
<title>Subclassing for Excel views</title>
<para>Exactly as we did for the XSLT example, we'll subclass suitable
@@ -1988,7 +1992,7 @@ pdf.(class)=pdf.HomePage</programlisting>
<para>Here's the complete listing for our POI Excel view which
displays the word list from the model map in consecutive rows of the
first column of a new spreadsheet:</para>
<programlisting language="java">package excel;
// imports omitted for brevity
@@ -2001,7 +2005,7 @@ public class HomePage extends AbstractExcelView {
HttpServletRequest req,
HttpServletResponse resp)
throws Exception {
HSSFSheet sheet;
HSSFRow sheetRow;
HSSFCell cell;
@@ -2027,7 +2031,7 @@ public class HomePage extends AbstractExcelView {
<para>And the following is a view generating the same Excel file, now using
JExcelApi:</para>
<programlisting language="java">package excel;
// imports omitted for brevity
@@ -2039,11 +2043,11 @@ public class HomePage extends AbstractJExcelView {
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
WritableSheet sheet = wb.createSheet("Spring", 0);
sheet.addCell(new Label(0, 0, "Spring-Excel test"));
List words = (List) model.get("wordList");
for (int i = 0; i &lt; words.size(); i++) {
sheet.addCell(new Label(2+i, 0, (String) words.get(i)));
@@ -2063,7 +2067,7 @@ public class HomePage extends AbstractJExcelView {
automatically when you request the same page as before.</para>
</section>
<section id="view-document-configsubclasspdf">
<section xml:id="view-document-configsubclasspdf">
<title>Subclassing for PDF views</title>
<para>The PDF version of the word list is even simpler. This time, the
@@ -2085,12 +2089,12 @@ public class PDFPage extends AbstractPdfView {
HttpServletRequest req,
HttpServletResponse resp)
throws Exception {
List words = (List) model.get("wordList");
for (int i=0; i&lt;words.size(); i++)
doc.add( new Paragraph((String) words.get(i)));
}
}</programlisting>
@@ -2103,17 +2107,17 @@ public class PDFPage extends AbstractPdfView {
</section>
</section>
<section id="view-jasper-reports">
<section xml:id="view-jasper-reports">
<title>JasperReports</title>
<para>JasperReports (<ulink
url="http://jasperreports.sourceforge.net"></ulink>) is a powerful
<para>JasperReports (<link
xl:href="http://jasperreports.sourceforge.net"></link>) is a powerful
open-source reporting engine that supports the creation of report designs
using an easily understood XML file format. JasperReports is capable of
rendering reports in four different formats: CSV, Excel, HTML and
PDF.</para>
<section id="view-jasper-reports-dependencies">
<section xml:id="view-jasper-reports-dependencies">
<title>Dependencies</title>
<para>Your application will need to include the latest release of
@@ -2153,7 +2157,7 @@ public class PDFPage extends AbstractPdfView {
<para>JasperReports also requires a JAXP compliant XML parser.</para>
</section>
<section id="view-jasper-reports-configuration">
<section xml:id="view-jasper-reports-configuration">
<title>Configuration</title>
<para>To configure JasperReports views in your Spring container
@@ -2162,7 +2166,7 @@ public class PDFPage extends AbstractPdfView {
appropriate view class depending on which format you want your report
rendered in.</para>
<section id="view-jasper-reports-configuration-resolver">
<section xml:id="view-jasper-reports-configuration-resolver">
<title>Configuring the
<interfacename>ViewResolver</interfacename></title>
@@ -2181,7 +2185,7 @@ public class PDFPage extends AbstractPdfView {
the next section.)</para>
</section>
<section id="view-jasper-reports-configuration-views">
<section xml:id="view-jasper-reports-configuration-views">
<title>Configuring the <literal>View</literal>s</title>
<para>The Spring Framework contains five different
@@ -2190,7 +2194,7 @@ public class PDFPage extends AbstractPdfView {
by JasperReports, and one that allows for the format to be determined
at runtime:</para>
<table id="view-jasper-reports-configuration-views-classes">
<table xml:id="view-jasper-reports-configuration-views-classes">
<title>JasperReports <interfacename>View</interfacename>
classes</title>
@@ -2258,7 +2262,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
the underlying report file.</para>
</section>
<section id="view-jasper-reports-configuration-report-files">
<section xml:id="view-jasper-reports-configuration-report-files">
<title>About Report Files</title>
<para>JasperReports has two distinct types of report file: the design
@@ -2276,7 +2280,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper</programlisting>
restart your application.</para>
</section>
<section id="view-jasper-reports-configuration-multiformat-view">
<section xml:id="view-jasper-reports-configuration-multiformat-view">
<title>Using
<classname>JasperReportsMultiFormatView</classname></title>
@@ -2317,7 +2321,7 @@ HttpServletResponse response) throws Exception {
<para>By default the following mapping key mappings are configured in
<classname>JasperReportsMultiFormatView</classname>:</para>
<table id="view-jasper-reports-configuration-multiformat-view-mappings">
<table xml:id="view-jasper-reports-configuration-multiformat-view-mappings">
<title><classname>JasperReportsMultiFormatView</classname> Default
Mapping Key Mappings</title>
@@ -2370,7 +2374,7 @@ HttpServletResponse response) throws Exception {
</section>
</section>
<section id="view-jasper-reports-model">
<section xml:id="view-jasper-reports-model">
<title>Populating the <classname>ModelAndView</classname></title>
<para>In order to render your report correctly in the format you have
@@ -2429,7 +2433,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
second approach.</para>
</section>
<section id="view-jasper-reports-subreports">
<section xml:id="view-jasper-reports-subreports">
<title>Working with Sub-Reports</title>
<para>JasperReports provides support for embedded sub-reports within
@@ -2442,7 +2446,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
configure sub-reports declaratively, and you can include additional data
for these sub-reports directly from your controllers.</para>
<section id="view-jasper-reports-subreports-config-reports">
<section xml:id="view-jasper-reports-subreports-config-reports">
<title>Configuring Sub-Report Files</title>
<para>To control which sub-report files are included in a master
@@ -2487,7 +2491,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
the JasperReports engine under the given key.</para>
</section>
<section id="view-jasper-reports-subreports-config-datasources">
<section xml:id="view-jasper-reports-subreports-config-datasources">
<title>Configuring Sub-Report Data Sources</title>
<para>This step is entirely optional when using Spring to configure your
@@ -2508,7 +2512,7 @@ simpleReport.reportDataKey=myBeanData</programlisting>
</section>
</section>
<section id="view-jasper-reports-exporter-parameters">
<section xml:id="view-jasper-reports-exporter-parameters">
<title>Configuring Exporter Parameters</title>
<para>If you have special requirements for exporter configuration --
@@ -2544,14 +2548,14 @@ simpleReport.reportDataKey=myBeanData</programlisting>
</section>
</section>
<section id="view-feeds">
<section xml:id="view-feeds">
<title>Feed Views</title>
<para>Both <classname>AbstractAtomFeedView</classname> and
<classname>AbstractRssFeedView</classname> inherit from the base class
<classname>AbstractFeedView</classname> and are used to provide Atom and
RSS Feed views respectfully. They are based on java.net's <ulink
url="https://rome.dev.java.net">ROME</ulink> project and are located in
RSS Feed views respectfully. They are based on java.net's <link
xl:href="https://rome.dev.java.net">ROME</link> project and are located in
the package
<literal>org.springframework.web.servlet.view.feed</literal>.</para>
@@ -2604,11 +2608,11 @@ simpleReport.reportDataKey=myBeanData</programlisting>
written to the response object after the method returns.</para>
<para>For an example of creating an Atom view please refer to Alef
Arendsen's SpringSource Team Blog <ulink
url="http://blog.springsource.com/2009/03/16/adding-an-atom-view-to-an-application-using-springs-rest-support/">entry</ulink>.</para>
Arendsen's SpringSource Team Blog <link
xl:href="http://blog.springsource.com/2009/03/16/adding-an-atom-view-to-an-application-using-springs-rest-support/">entry</link>.</para>
</section>
<section id="view-xml-marshalling">
<section xml:id="view-xml-marshalling">
<title>XML Marshalling View</title>
<para>The <classname>MarhsallingView</classname> uses an XML
@@ -2624,28 +2628,28 @@ simpleReport.reportDataKey=myBeanData</programlisting>
chapter <link linkend="oxm">Marshalling XML using O/X
Mappers</link>.</para>
</section>
<section id="view-json-mapping">
<title>JSON Mapping View</title>
<section xml:id="view-json-mapping">
<title>JSON Mapping View</title>
<para>The <classname>MappingJackson2JsonView</classname>
(or <classname>MappingJacksonJsonView</classname> depending on the
the Jackson version you have) uses the Jackson
library's <classname>ObjectMapper</classname> to render the response content
as JSON. By default, the entire contents of the model map (with the exception
of framework-specific classes) will be encoded as JSON. For cases where the
contents of the map need to be filtered, users may specify a specific set of
model attributes to encode via the <literal>RenderedAttributes</literal>
property. The <literal>extractValueFromSingleKeyModel</literal> property
may also be used to have the value in single-key models extracted and
serialized directly rather than as a map of model attributes.</para>
library's <classname>ObjectMapper</classname> to render the response content
as JSON. By default, the entire contents of the model map (with the exception
of framework-specific classes) will be encoded as JSON. For cases where the
contents of the map need to be filtered, users may specify a specific set of
model attributes to encode via the <literal>RenderedAttributes</literal>
property. The <literal>extractValueFromSingleKeyModel</literal> property
may also be used to have the value in single-key models extracted and
serialized directly rather than as a map of model attributes.</para>
<para>JSON mapping can be customized as needed through the use of Jackson's provided
annotations. When further control is needed, a custom
<interfacename>ObjectMapper</interfacename> can be injected through the
<literal>ObjectMapper</literal> property for cases where custom JSON
serializers/deserializers need to be provided for specific types.</para>
<para>JSON mapping can be customized as needed through the use of Jackson's provided
annotations. When further control is needed, a custom
<interfacename>ObjectMapper</interfacename> can be injected through the
<literal>ObjectMapper</literal> property for cases where custom JSON
serializers/deserializers need to be provided for specific types.</para>
</section>
</chapter>

View File

@@ -1,19 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<chapter xml:id="web-integration"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="web-integration">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Integrating with other web frameworks</title>
<section id="intro">
<section xml:id="intro">
<title>Introduction</title>
<para>This chapter details Spring's integration with third party web
frameworks such as <ulink
url="http://java.sun.com/javaee/javaserverfaces/">JSF</ulink>, <ulink
url="http://struts.apache.org/">Struts</ulink>, <ulink
url="http://www.opensymphony.com/webwork/">WebWork</ulink>, and <ulink
url="http://tapestry.apache.org/">Tapestry</ulink>.</para>
frameworks such as <link
xl:href="http://java.sun.com/javaee/javaserverfaces/">JSF</link>, <link
xl:href="http://struts.apache.org/">Struts</link>, <link
xl:href="http://www.opensymphony.com/webwork/">WebWork</link>, and <link
xl:href="http://tapestry.apache.org/">Tapestry</link>.</para>
<!-- insert some content about Spring Web Flow here -->
@@ -46,7 +50,7 @@
popular web frameworks in Java, starting with the Spring configuration
that is common to all of the supported web frameworks, and then detailing
the specific integration options for each supported web framework.</para>
<note>
<para>Please note that this chapter does not attempt to explain
how to use any of the supported web frameworks. For example, if you want
@@ -60,7 +64,7 @@
</section>
<section id="web-integration-common">
<section xml:id="web-integration-common">
<title>Common configuration</title>
<para>Before diving into the integration specifics of each supported web
@@ -83,8 +87,8 @@
a Spring container (a <classname>WebApplicationContext</classname>) that
contains all of the 'business beans' in one's application.</para>
<para>On to specifics: all that one need do is to declare a <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/context/ContextLoaderListener.html"><classname>ContextLoaderListener</classname></ulink>
<para>On to specifics: all that one need do is to declare a <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/context/ContextLoaderListener.html"><classname>ContextLoaderListener</classname></link>
in the standard Java EE servlet <literal>web.xml</literal> file of one's web
application, and add a <literal>contextConfigLocation</literal>
&lt;context-param/&gt; section (in the same file) that defines which set
@@ -106,29 +110,29 @@
<para>If you don't specify the <literal>contextConfigLocation</literal>
context parameter, the <classname>ContextLoaderListener</classname> will
look for a file called <literal>/WEB-INF/applicationContext.xml</literal>
to load. Once the context files are loaded, Spring creates a <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/context/WebApplicationContext.html"><classname>WebApplicationContext</classname></ulink>
to load. Once the context files are loaded, Spring creates a <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/context/WebApplicationContext.html"><classname>WebApplicationContext</classname></link>
object based on the bean definitions and stores it in the
<interface>ServletContext</interface> of the web application.</para>
<interfacename>ServletContext</interfacename> of the web application.</para>
<para>All Java web frameworks are built on top of the Servlet API, and so
one can use the following code snippet to get access to this 'business
context' <interface>ApplicationContext</interface> created by the
context' <interfacename>ApplicationContext</interfacename> created by the
<classname>ContextLoaderListener</classname>.</para>
<programlisting language="java">WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);</programlisting>
<para>The <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/context/support/WebApplicationContextUtils.html"><classname>WebApplicationContextUtils</classname></ulink>
<para>The <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/context/support/WebApplicationContextUtils.html"><classname>WebApplicationContextUtils</classname></link>
class is for convenience, so you don't have to remember the name of the
<interface>ServletContext</interface> attribute. Its
<interfacename>ServletContext</interfacename> attribute. Its
<emphasis>getWebApplicationContext()</emphasis> method will return
<literal>null</literal> if an object doesn't exist under the
<literal>WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE</literal>
key. Rather than risk getting <classname>NullPointerExceptions</classname>
in your application, it's better to use the
<literal>getRequiredWebApplicationContext()</literal> method. This method
throws an exception when the <interface>ApplicationContext</interface> is
throws an exception when the <interfacename>ApplicationContext</interfacename> is
missing.</para>
<para>Once you have a reference to the
@@ -143,7 +147,7 @@
specific integration strategies.</para>
</section>
<section id="jsf">
<section xml:id="jsf">
<title>JavaServer Faces 1.1 and 1.2</title>
<para>JavaServer Faces (JSF) is the JCP's standard component-based,
@@ -151,10 +155,10 @@
official part of the Java EE umbrella.</para>
<para>For a popular JSF runtime as well as for popular JSF component
libraries, check out the <ulink url="http://myfaces.apache.org/">Apache
MyFaces project</ulink>. The MyFaces project also provides common JSF
extensions such as <ulink
url="http://myfaces.apache.org/orchestra/">MyFaces Orchestra</ulink>: a
libraries, check out the <link xl:href="http://myfaces.apache.org/">Apache
MyFaces project</link>. The MyFaces project also provides common JSF
extensions such as <link
xl:href="http://myfaces.apache.org/orchestra/">MyFaces Orchestra</link>: a
Spring-based JSF extension that provides rich conversation scope
support.</para>
@@ -162,9 +166,9 @@
<para>Spring Web Flow 2.0 provides rich JSF support through its newly
established Spring Faces module, both for JSF-centric usage (as
described in this section) and for Spring-centric usage (using JSF views
within a Spring MVC dispatcher). Check out the <ulink
url="http://www.springframework.org/webflow">Spring Web Flow
website</ulink> for details!</para>
within a Spring MVC dispatcher). Check out the <link
xl:href="http://www.springframework.org/webflow">Spring Web Flow
website</link> for details!</para>
</note>
<para>The key element in Spring's JSF integration is the JSF 1.1
@@ -172,13 +176,13 @@
supports the <classname>ELResolver</classname> mechanism as a
next-generation version of JSF EL integration.</para>
<section id="jsf-delegatingvariableresolver">
<section xml:id="jsf-delegatingvariableresolver">
<title>DelegatingVariableResolver (JSF 1.1/1.2)</title>
<para>The easiest way to integrate one's Spring middle-tier with one's
JSF web layer is to use the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/jsf/DelegatingVariableResolver.html">
<classname>DelegatingVariableResolver</classname></ulink> class. To
JSF web layer is to use the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/jsf/DelegatingVariableResolver.html">
<classname>DelegatingVariableResolver</classname></link> class. To
configure this variable resolver in one's application, one will need to
edit one's <emphasis>faces-context.xml</emphasis> file. After the
opening <literal>&lt;faces-config/&gt;</literal> element, add an
@@ -221,7 +225,7 @@
&lt;/managed-bean&gt;</programlisting>
</section>
<section id="jsf-springbeanvariableresolver">
<section xml:id="jsf-springbeanvariableresolver">
<title>SpringBeanVariableResolver (JSF 1.1/1.2)</title>
<para><classname>SpringBeanVariableResolver</classname> is a variant of
@@ -245,7 +249,7 @@
&lt;/faces-config&gt;</programlisting>
</section>
<section id="jsf-springbeanfaceselresolver">
<section xml:id="jsf-springbeanfaceselresolver">
<title>SpringBeanFacesELResolver (JSF 1.2+)</title>
<para><classname>SpringBeanFacesELResolver</classname> is a JSF 1.2
@@ -268,31 +272,31 @@
&lt;/faces-config&gt;</programlisting>
</section>
<section id="jsf-facescontextutils">
<section xml:id="jsf-facescontextutils">
<title>FacesContextUtils</title>
<para>A custom <interfacename>VariableResolver</interfacename> works
well when mapping one's properties to beans in
<emphasis>faces-config.xml</emphasis>, but at times one may need to grab
a bean explicitly. The <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/jsf/FacesContextUtils.html">
<classname>FacesContextUtils</classname></ulink> class makes this easy.
a bean explicitly. The <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/jsf/FacesContextUtils.html">
<classname>FacesContextUtils</classname></link> class makes this easy.
It is similar to <classname>WebApplicationContextUtils</classname>,
except that it takes a <classname>FacesContext</classname> parameter
rather than a <interface>ServletContext</interface> parameter.</para>
rather than a <interfacename>ServletContext</interfacename> parameter.</para>
<programlisting language="java">ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());</programlisting>
</section>
</section>
<section id="struts">
<section xml:id="struts">
<title>Apache Struts 1.x and 2.x</title>
<para><ulink url="http://struts.apache.org">Struts</ulink> used to be the
<para><link xl:href="http://struts.apache.org">Struts</link> used to be the
<emphasis>de facto</emphasis> web framework for Java applications, mainly
because it was one of the first to be released (June 2001). It has now been renamed to <emphasis>Struts 1</emphasis>
(as opposed to Struts 2). Many applications still use it.
Invented by Craig McClanahan, Struts is an open source project hosted by the Apache
because it was one of the first to be released (June 2001). It has now been renamed to <emphasis>Struts 1</emphasis>
(as opposed to Struts 2). Many applications still use it.
Invented by Craig McClanahan, Struts is an open source project hosted by the Apache
Software Foundation. At the time, it greatly simplified the JSP/Servlet
programming paradigm and won over many developers who were using
proprietary frameworks. It simplified the programming model, it was open
@@ -306,9 +310,9 @@
<para>Struts 2 is effectively a different product - a successor of
WebWork 2.2 (as discussed in <xref linkend="webwork" />), carrying the
Struts brand now. Check out the Struts 2 <ulink
url="http://struts.apache.org/2.x/docs/spring-plugin.html">Spring
Plugin</ulink> for the built-in Spring integration shipped with Struts
Struts brand now. Check out the Struts 2 <link
xl:href="http://struts.apache.org/2.x/docs/spring-plugin.html">Spring
Plugin</link> for the built-in Spring integration shipped with Struts
2. In general, Struts 2 is closer to WebWork 2.2 than to Struts 1 in
terms of its Spring integration implications.</para>
</note>
@@ -330,11 +334,11 @@
</listitem>
</itemizedlist>
<section id="struts-contextloaderplugin">
<section xml:id="struts-contextloaderplugin">
<title>ContextLoaderPlugin</title>
<para>The <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/ContextLoaderPlugIn.html"><classname>ContextLoaderPlugin</classname></ulink>
<para>The <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/ContextLoaderPlugIn.html"><classname>ContextLoaderPlugin</classname></link>
is a Struts 1.1+ plug-in that loads a Spring context file for the Struts
<classname>ActionServlet</classname>. This context refers to the root
<classname>WebApplicationContext</classname> (loaded by the
@@ -363,9 +367,9 @@
which can be useful when using testing tools like StrutsTestCase.
StrutsTestCase's <classname>MockStrutsTestCase</classname> won't
initialize Listeners on startup so putting all your context files in the
plugin is a workaround. (A <ulink
url="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088866&amp;group_id=39190&amp;atid=424562">
bug has been filed</ulink> for this issue, but has been closed as 'Wont
plugin is a workaround. (A <link
xl:href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1088866&amp;group_id=39190&amp;atid=424562">
bug has been filed</link> for this issue, but has been closed as 'Wont
Fix').</para>
<para>After configuring this plug-in in
@@ -401,12 +405,12 @@
<programlisting language="xml">&lt;bean name="/users" .../&gt;</programlisting>
<section id="struts-delegatingrequestprocessor">
<section xml:id="struts-delegatingrequestprocessor">
<title>DelegatingRequestProcessor</title>
<para>To configure the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingRequestProcessor.html">
<literal>DelegatingRequestProcessor</literal></ulink> in your
<para>To configure the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingRequestProcessor.html">
<literal>DelegatingRequestProcessor</literal></link> in your
<emphasis>struts-config.xml</emphasis> file, override the
"processorClass" property in the &lt;controller&gt; element. These
lines follow the &lt;action-mapping&gt; element.</para>
@@ -432,21 +436,21 @@
<note>
<para>If you are using Tiles in your Struts application, you must
configure your &lt;controller&gt; with the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingTilesRequestProcessor.html"><classname>DelegatingTilesRequestProcessor</classname></ulink>
configure your &lt;controller&gt; with the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingTilesRequestProcessor.html"><classname>DelegatingTilesRequestProcessor</classname></link>
instead.</para>
</note>
</section>
<section id="struts-delegatingactionproxy">
<section xml:id="struts-delegatingactionproxy">
<title>DelegatingActionProxy</title>
<para>If you have a custom <classname>RequestProcessor</classname> and
can't use the <classname>DelegatingRequestProcessor</classname> or
<classname>DelegatingTilesRequestProcessor</classname> approaches, you
can use the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingActionProxy.html">
<classname>DelegatingActionProxy</classname></ulink> as the type in
can use the <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingActionProxy.html">
<classname>DelegatingActionProxy</classname></link> as the type in
your action-mapping.</para>
<programlisting language="xml">&lt;action path="/user" type="org.springframework.web.struts.DelegatingActionProxy"
@@ -473,18 +477,18 @@
</section>
</section>
<section id="struts-actionsupport">
<section xml:id="struts-actionsupport">
<title>ActionSupport Classes</title>
<para>As previously mentioned, you can retrieve the
<classname>WebApplicationContext</classname> from the
<interface>ServletContext</interface> using the
<interfacename>ServletContext</interfacename> using the
<classname>WebApplicationContextUtils</classname> class. An easier way
is to extend Spring's <classname>Action</classname> classes for Struts.
For example, instead of subclassing Struts'
<classname>Action</classname> class, you can subclass Spring's <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/ActionSupport.html">
<classname>ActionSupport</classname></ulink> class.</para>
<classname>Action</classname> class, you can subclass Spring's <link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/ActionSupport.html">
<classname>ActionSupport</classname></link> class.</para>
<para>The <classname>ActionSupport</classname> class provides additional
convenience methods, like
@@ -511,24 +515,24 @@
- the Spring versions merely have <emphasis>Support</emphasis> appended
to the name: <itemizedlist spacing="compact">
<listitem>
<para><ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/ActionSupport.html"><classname>ActionSupport</classname></ulink>,</para>
<para><link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/ActionSupport.html"><classname>ActionSupport</classname></link>,</para>
</listitem>
<listitem>
<para><ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DispatchActionSupport.html"><literal>DispatchActionSupport</literal></ulink>,</para>
<para><link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DispatchActionSupport.html"><literal>DispatchActionSupport</literal></link>,</para>
</listitem>
<listitem>
<para><ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/LookupDispatchActionSupport.html"><literal>LookupDispatchActionSupport</literal></ulink>
<para><link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/LookupDispatchActionSupport.html"><literal>LookupDispatchActionSupport</literal></link>
and</para>
</listitem>
<listitem>
<para><ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/MappingDispatchActionSupport.html"><literal>MappingDispatchActionSupport</literal></ulink>.</para>
<para><link
xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/MappingDispatchActionSupport.html"><literal>MappingDispatchActionSupport</literal></link>.</para>
</listitem>
</itemizedlist></para>
@@ -541,12 +545,12 @@
</section>
</section>
<section id="webwork">
<section xml:id="webwork">
<title>WebWork 2.x</title>
<para>From the <ulink url="http://www.opensymphony.com/webwork/">WebWork
homepage</ulink>:</para>
<para>From the <link xl:href="http://www.opensymphony.com/webwork/">WebWork
homepage</link>:</para>
<para>
<quote>
<emphasis>WebWork is a Java web-application development framework. It is
@@ -562,9 +566,9 @@
understand, and the framework also has an extensive tag library as well as
nicely decoupled validation.</para>
<para>One of the key enablers in WebWork's technology stack is <ulink
url="http://www.opensymphony.com/webwork/wikidocs/IoC%20Overview.html">an
IoC container</ulink> to manage Webwork Actions, handle the "wiring" of
<para>One of the key enablers in WebWork's technology stack is <link
xl:href="http://www.opensymphony.com/webwork/wikidocs/IoC%20Overview.html">an
IoC container</link> to manage Webwork Actions, handle the "wiring" of
business objects, etc. Prior to WebWork version 2.2, WebWork used its own
proprietary IoC container (and provided integration points so that one
could integrate an IoC container such as Spring's into the mix). However,
@@ -577,10 +581,10 @@
<para>Now in the interests of adhering to the DRY (Don't Repeat Yourself)
principle, it would be foolish to document the Spring-WebWork integration
in light of the fact that the WebWork team have already written such a
writeup. Please consult the <ulink
url="http://www.opensymphony.com/webwork/wikidocs/Spring.html">Spring-WebWork
integration page</ulink> on the <ulink
url="http://wiki.opensymphony.com/display/WW/WebWork">WebWork wiki</ulink>
writeup. Please consult the <link
xl:href="http://www.opensymphony.com/webwork/wikidocs/Spring.html">Spring-WebWork
integration page</link> on the <link
xl:href="http://wiki.opensymphony.com/display/WW/WebWork">WebWork wiki</link>
for the full lowdown.</para>
<para>Note that the Spring-WebWork integration code was developed (and
@@ -588,16 +592,16 @@
themselves. So please refer first to the WebWork site and forums if you are
having issues with the integration. But feel free to
post comments and queries regarding the Spring-WebWork integration on the
<ulink url="http://forum.springframework.org/forumdisplay.php?f=25">Spring
support forums</ulink>, too.</para>
<link xl:href="http://forum.springframework.org/forumdisplay.php?f=25">Spring
support forums</link>, too.</para>
</section>
<section id="tapestry">
<section xml:id="tapestry">
<title>Tapestry 3.x and 4.x</title>
<para>From the <ulink url="http://tapestry.apache.org/">Tapestry
homepage</ulink>:</para>
<para>From the <link xl:href="http://tapestry.apache.org/">Tapestry
homepage</link>:</para>
<para>
<quote>
<emphasis>Tapestry is an open-source framework for creating dynamic,
@@ -621,7 +625,7 @@
contains the following snippet of best practice advice. (Text that the
author of this Spring section has added is contained within
<literal>[]</literal> brackets.)</para>
<para>
<quote>
<emphasis>A very successful design pattern in Tapestry is to keep pages
@@ -643,11 +647,11 @@
Tapestry itself makes doing this dependency injection of Spring-managed
beans a cinch. (Another nice thing is that this Spring-Tapestry
integration code was written - and continues to be maintained - by the
Tapestry creator <ulink url="http://howardlewisship.com/blog/">Howard M.
Lewis Ship</ulink>, so hats off to him for what is really some silky
Tapestry creator <link xl:href="http://howardlewisship.com/blog/">Howard M.
Lewis Ship</link>, so hats off to him for what is really some silky
smooth integration).</para>
<section id="tapestry-di">
<section xml:id="tapestry-di">
<title>Injecting Spring-managed beans</title>
<para>Assume we have the following simple Spring container definition
@@ -660,26 +664,26 @@
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
<emphasis role="bold">http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"</emphasis>&gt;
&lt;beans&gt;
&lt;!-- the DataSource --&gt;
&lt;jee:jndi-lookup id="dataSource" jndi-name="java:DefaultDS"/&gt;
&lt;bean id="hibSessionFactory"
&lt;bean id="hibSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;
&lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
&lt;bean id="transactionManager"
&lt;bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/&gt;
&lt;bean id="mapper"
&lt;bean id="mapper"
class="com.whatever.dataaccess.mapper.hibernate.MapperImpl"&gt;
&lt;property name="sessionFactory" ref="hibSessionFactory"/&gt;
&lt;/bean&gt;
&lt;!-- (transactional) AuthenticationService --&gt;
&lt;bean id="authenticationService"
&lt;bean id="authenticationService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
&lt;property name="transactionManager" ref="transactionManager"/&gt;
&lt;property name="target"&gt;
@@ -693,10 +697,10 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
*=PROPAGATION_REQUIRED
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/bean&gt;
&lt;!-- (transactional) UserService --&gt;
&lt;bean id="userService"
&lt;bean id="userService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
&lt;property name="transactionManager" ref="transactionManager"/&gt;
&lt;property name="target"&gt;
@@ -710,8 +714,8 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
*=PROPAGATION_REQUIRED
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
<para>Inside the Tapestry application, the above bean definitions need
@@ -727,7 +731,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
application by calling Spring's static utility function
<literal>WebApplicationContextUtils.getApplicationContext(servletContext)</literal>,
where servletContext is the standard
<interface>ServletContext</interface> from the Java EE Servlet
<interfacename>ServletContext</interfacename> from the Java EE Servlet
specification. As such, one simple mechanism for a page to get an
instance of the <interfacename>UserService</interfacename>, for example,
would be with code such as:</para>
@@ -757,16 +761,16 @@ UserService userService = (UserService) appContext.getBean("userService");
linkend="tapestry-4-style-di" />.</para>
</note>
<section id="tapestry-pre4-style-di">
<section xml:id="tapestry-pre4-style-di">
<title>Dependency Injecting Spring Beans into Tapestry pages</title>
<para>First we need to make the
<interface>ApplicationContext</interface> available to the Tapestry
<interfacename>ApplicationContext</interfacename> available to the Tapestry
page or Component without having to have the
<interface>ServletContext</interface>; this is because at the stage in
<interfacename>ServletContext</interfacename>; this is because at the stage in
the page's/component's lifecycle when we need to access the
<interface>ApplicationContext</interface>, the
<interface>ServletContext</interface> won't be easily available to the
<interfacename>ApplicationContext</interfacename>, the
<interfacename>ServletContext</interfacename> won't be easily available to the
page, so we can't use
<literal>WebApplicationContextUtils.getApplicationContext(servletContext)</literal>
directly. One way is by defining a custom version of the Tapestry
@@ -778,15 +782,15 @@ UserService userService = (UserService) appContext.getBean("userService");
// import ...
public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
public static final String APPLICATION_CONTEXT_KEY = "appContext";
/**
* @see org.apache.tapestry.engine.AbstractEngine#setupForRequest(org.apache.tapestry.request.RequestContext)
*/
protected void setupForRequest(RequestContext context) {
super.setupForRequest(context);
// insert ApplicationContext in global, if not there
Map global = (Map) getGlobal();
ApplicationContext ac = (ApplicationContext) global.get(APPLICATION_CONTEXT_KEY);
@@ -807,8 +811,8 @@ public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
<programlisting language="xml"><lineannotation>file: xportal.application:</lineannotation>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE application PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
&lt;!DOCTYPE application PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd"&gt;
&lt;application
name="Whatever xPortal"
@@ -816,7 +820,7 @@ public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
&lt;/application&gt;</programlisting>
</section>
<section id="tapestry-componentdefs">
<section xml:id="tapestry-componentdefs">
<title>Component definition files</title>
<para>Now in our page or component definition file (*.page or *.jwc),
@@ -838,12 +842,12 @@ public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
context. The entire page definition might look like this:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE page-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
&lt;!DOCTYPE page-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd"&gt;
&lt;page-specification class="com.whatever.web.xportal.pages.Login"&gt;
&lt;property-specification name="username" type="java.lang.String"/&gt;
&lt;property-specification name="password" type="java.lang.String"/&gt;
&lt;property-specification name="error" type="java.lang.String"/&gt;
@@ -856,31 +860,31 @@ public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
type="com.whatever.services.service.user.AuthenticationService"&gt;
global.appContext.getBean("authenticationService")
&lt;/property-specification&gt;
&lt;bean name="delegate" class="com.whatever.web.xportal.PortalValidationDelegate"/&gt;
&lt;bean name="validator" class="org.apache.tapestry.valid.StringValidator" lifecycle="page"&gt;
&lt;set-property name="required" expression="true"/&gt;
&lt;set-property name="clientScriptingEnabled" expression="true"/&gt;
&lt;/bean&gt;
&lt;component id="inputUsername" type="ValidField"&gt;
&lt;static-binding name="displayName" value="Username"/&gt;
&lt;binding name="value" expression="username"/&gt;
&lt;binding name="validator" expression="beans.validator"/&gt;
&lt;/component&gt;
&lt;component id="inputPassword" type="ValidField"&gt;
&lt;binding name="value" expression="password"/&gt;
&lt;binding name="validator" expression="beans.validator"/&gt;
&lt;static-binding name="displayName" value="Password"/&gt;
&lt;binding name="hidden" expression="true"/&gt;
&lt;/component&gt;
&lt;/page-specification&gt;</programlisting>
</section>
<section id="tapestry-getters">
<section xml:id="tapestry-getters">
<title>Adding abstract accessors</title>
<para>Now in the Java class definition for the page or component
@@ -897,7 +901,7 @@ public abstract AuthenticationService getAuthenticationService();</programlistin
page in this example, might look like this:</para>
<programlisting language="java">package com.whatever.web.xportal.pages;
/**
* Allows the user to login, by providing username and password.
* After successfully logging in, a cookie is placed on the client browser
@@ -905,54 +909,54 @@ public abstract AuthenticationService getAuthenticationService();</programlistin
* persists for a week).
*/
public abstract class Login extends BasePage implements ErrorProperty, PageRenderListener {
/** the key under which the authenticated user object is stored in the visit as */
public static final String USER_KEY = "user";
/** The name of the cookie that identifies a user **/
private static final String COOKIE_NAME = Login.class.getName() + ".username";
private static final String COOKIE_NAME = Login.class.getName() + ".username";
private final static int ONE_WEEK = 7 * 24 * 60 * 60;
public abstract String getUsername();
public abstract void setUsername(String username);
public abstract String getPassword();
public abstract void setPassword(String password);
public abstract ICallback getCallback();
public abstract void setCallback(ICallback value);
public abstract UserService getUserService();
public abstract AuthenticationService getAuthenticationService();
protected IValidationDelegate getValidationDelegate() {
return (IValidationDelegate) getBeans().getBean("delegate");
}
protected void setErrorField(String componentId, String message) {
IFormComponent field = (IFormComponent) getComponent(componentId);
IValidationDelegate delegate = getValidationDelegate();
delegate.setFormComponent(field);
delegate.record(new ValidatorException(message));
}
/**
* Attempts to login.
* Attempts to login.
* &lt;p&gt;
* If the user name is not known, or the password is invalid, then an error
* message is displayed.
**/
public void attemptLogin(IRequestCycle cycle) {
String password = getPassword();
// Do a little extra work to clear out the password.
setPassword(null);
IValidationDelegate delegate = getValidationDelegate();
delegate.setFormComponent((IFormComponent) getComponent("inputPassword"));
delegate.recordFieldInputValue(null);
// An error, from a validation field, may already have occurred.
if (delegate.getHasErrors()) {
return;
@@ -967,7 +971,7 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
return;
}
}
/**
* Sets up the {@link User} as the logged in user, creates
* a cookie for their username (for subsequent logins),
@@ -975,17 +979,17 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
* a specified page).
**/
public void loginUser(User user, IRequestCycle cycle) {
String username = user.getUsername();
// Get the visit object; this will likely force the
// creation of the visit object and an HttpSession
Map visit = (Map) getVisit();
visit.put(USER_KEY, user);
// After logging in, go to the MyLibrary page, unless otherwise specified
ICallback callback = getCallback();
if (callback == null) {
cycle.activate("Home");
}
@@ -997,12 +1001,12 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
Cookie cookie = new Cookie(COOKIE_NAME, username);
cookie.setPath(engine.getServletPath());
cookie.setMaxAge(ONE_WEEK);
// Record the user's username in a cookie
cycle.getRequestContext().addCookie(cookie);
engine.forgetPage(getPageName());
}
public void pageBeginRender(PageEvent event) {
if (getUsername() == null) {
setUsername(getRequestCycle().getRequestContext().getCookieValue(COOKIE_NAME));
@@ -1011,15 +1015,15 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
}</programlisting>
</section>
<section id="tapestry-4-style-di">
<section xml:id="tapestry-4-style-di">
<title>Dependency Injecting Spring Beans into Tapestry pages -
Tapestry 4.x style</title>
<para>Effecting the dependency injection of Spring-managed beans into
Tapestry pages in Tapestry version 4.x is <emphasis>so</emphasis> much
simpler. All that is needed is a single <ulink
url="http://howardlewisship.com/tapestry-javaforge/tapestry-spring/">add-on
library</ulink>, and some (small) amount of (essentially boilerplate)
simpler. All that is needed is a single <link
xl:href="http://howardlewisship.com/tapestry-javaforge/tapestry-spring/">add-on
library</link>, and some (small) amount of (essentially boilerplate)
configuration. Simply package and deploy this library with the (any of
the) other libraries required by your web application (typically in
<literal>WEB-INF/lib</literal>).</para>
@@ -1037,10 +1041,10 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
<programlisting language="java">package com.whatever.web.xportal.pages;
public abstract class Login extends BasePage implements ErrorProperty, PageRenderListener {
@InjectObject("spring:userService")
public abstract UserService getUserService();
@InjectObject("spring:authenticationService")
public abstract AuthenticationService getAuthenticationService();
@@ -1099,7 +1103,7 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
</section>
<section id="web-integration-resources">
<section xml:id="web-integration-resources">
<title>Further Resources</title>
<para>Find below links to further resources about the various web
@@ -1107,24 +1111,24 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende
<itemizedlist>
<listitem>
<para>The <ulink
url="http://java.sun.com/javaee/javaserverfaces/">JSF</ulink>
<para>The <link
xl:href="http://java.sun.com/javaee/javaserverfaces/">JSF</link>
homepage</para>
</listitem>
<listitem>
<para>The <ulink url="http://struts.apache.org/">Struts</ulink>
<para>The <link xl:href="http://struts.apache.org/">Struts</link>
homepage</para>
</listitem>
<listitem>
<para>The <ulink
url="http://www.opensymphony.com/webwork/">WebWork</ulink>
<para>The <link
xl:href="http://www.opensymphony.com/webwork/">WebWork</link>
homepage</para>
</listitem>
<listitem>
<para>The <ulink url="http://tapestry.apache.org/">Tapestry</ulink>
<para>The <link xl:href="http://tapestry.apache.org/">Tapestry</link>
homepage</para>
</listitem>
</itemizedlist>

View File

@@ -1,24 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<appendix xml:id="extensible-xml"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="extensible-xml">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>Extensible XML authoring</title>
<section id="extensible-xml-introduction">
<section xml:id="extensible-xml-introduction">
<title>Introduction</title>
<para>Since version 2.0, Spring has featured a mechanism for schema-based extensions
to the basic Spring XML format for defining and configuring beans. This section is
devoted to detailing how you would go about writing your own custom XML bean definition
parsers and integrating such parsers into the Spring IoC container.</para>
<para>To facilitate the authoring of configuration files using a schema-aware XML editor,
Spring's extensible XML configuration mechanism is based on XML Schema. If you are
not familiar with Spring's current XML configuration extensions that come with the
standard Spring distribution, please first read the appendix entitled
<xref linkend="xsd-config"/>.</para>
<para>Creating new XML configuration extensions can be done by following these (relatively)
simple steps:</para>
<para>
<orderedlist numeration="arabic">
<para>To facilitate the authoring of configuration files using a schema-aware XML editor,
Spring's extensible XML configuration mechanism is based on XML Schema. If you are
not familiar with Spring's current XML configuration extensions that come with the
standard Spring distribution, please first read the appendix entitled
<xref linkend="xsd-config"/>.</para>
<para>Creating new XML configuration extensions can be done by following these (relatively)
simple steps:</para>
<para>
<orderedlist numeration="arabic">
<listitem>
<para><link linkend="extensible-xml-schema">Authoring</link> an XML schema to describe your custom element(s).</para>
</listitem>
@@ -33,14 +37,14 @@
<listitem>
<para><link linkend="extensible-xml-registration">Registering</link> the above artifacts with Spring (this too is an easy step).</para>
</listitem>
</orderedlist>
</para>
<para>What follows is a description of each of these steps. For the example, we will create
an XML extension (a custom XML element) that allows us to configure objects of the type
<classname>SimpleDateFormat</classname> (from the <literal>java.text</literal> package)
in an easy manner. When we are done, we will be able to define bean definitions of type
<classname>SimpleDateFormat</classname> like this:</para>
<programlisting language="xml"><![CDATA[<myns:dateformat id="dateFormat"
</orderedlist>
</para>
<para>What follows is a description of each of these steps. For the example, we will create
an XML extension (a custom XML element) that allows us to configure objects of the type
<classname>SimpleDateFormat</classname> (from the <literal>java.text</literal> package)
in an easy manner. When we are done, we will be able to define bean definitions of type
<classname>SimpleDateFormat</classname> like this:</para>
<programlisting language="xml"><![CDATA[<myns:dateformat id="dateFormat"
pattern="yyyy-MM-dd HH:mm"
lenient="true"/>
]]></programlisting>
@@ -48,13 +52,13 @@
detailed examples follow afterwards. The intent in this first simple example is to walk
you through the basic steps involved.)</emphasis></para>
</section>
<section id="extensible-xml-schema">
<title>Authoring the schema</title>
<para>Creating an XML configuration extension for use with Spring's IoC container
starts with authoring an XML Schema to describe the extension. What follows
is the schema we'll use to configure <classname>SimpleDateFormat</classname>
objects.</para>
<programlisting language="xml"><lineannotation>&lt;!-- myns.xsd (inside package org/springframework/samples/xml) --&gt;</lineannotation><![CDATA[
<section xml:id="extensible-xml-schema">
<title>Authoring the schema</title>
<para>Creating an XML configuration extension for use with Spring's IoC container
starts with authoring an XML Schema to describe the extension. What follows
is the schema we'll use to configure <classname>SimpleDateFormat</classname>
objects.</para>
<programlisting language="xml"><lineannotation>&lt;!-- myns.xsd (inside package org/springframework/samples/xml) --&gt;</lineannotation><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.mycompany.com/schema/myns"
@@ -79,80 +83,80 @@
</xsd:schema>]]></programlisting>
<para>(The emphasized line contains an extension base for all tags that
will be identifiable (meaning they have an <literal>id</literal> attribute
that will be used as the bean identifier in the container). We are able to use this
attribute because we imported the Spring-provided <literal>'beans'</literal>
namespace.)</para>
<para>The above schema will be used to configure <classname>SimpleDateFormat</classname>
objects, directly in an XML application context file using the
<literal>&lt;myns:dateformat/&gt;</literal> element.</para>
<programlisting language="xml"><![CDATA[<myns:dateformat id="dateFormat"
will be identifiable (meaning they have an <literal>id</literal> attribute
that will be used as the bean identifier in the container). We are able to use this
attribute because we imported the Spring-provided <literal>'beans'</literal>
namespace.)</para>
<para>The above schema will be used to configure <classname>SimpleDateFormat</classname>
objects, directly in an XML application context file using the
<literal>&lt;myns:dateformat/&gt;</literal> element.</para>
<programlisting language="xml"><![CDATA[<myns:dateformat id="dateFormat"
pattern="yyyy-MM-dd HH:mm"
lenient="true"/>
]]></programlisting>
<para>Note that after we've created the infrastructure classes, the above snippet of XML
will essentially be exactly the same as the following XML snippet. In other words,
we're just creating a bean in the container, identified by the name
<literal>'dateFormat'</literal> of type <classname>SimpleDateFormat</classname>, with a
couple of properties set.</para>
<programlisting language="xml"><![CDATA[<bean id="dateFormat" class="java.text.SimpleDateFormat">
<para>Note that after we've created the infrastructure classes, the above snippet of XML
will essentially be exactly the same as the following XML snippet. In other words,
we're just creating a bean in the container, identified by the name
<literal>'dateFormat'</literal> of type <classname>SimpleDateFormat</classname>, with a
couple of properties set.</para>
<programlisting language="xml"><![CDATA[<bean id="dateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-HH-dd HH:mm"/>
<property name="lenient" value="true"/>
</bean>]]></programlisting>
<note>
<para>The schema-based approach to creating configuration format allows for
tight integration with an IDE that has a schema-aware XML editor. Using a properly
authored schema, you can use autocompletion to have a user choose between several
configuration options defined in the enumeration.</para>
</note>
</section>
<section id="extensible-xml-namespacehandler">
<title>Coding a <interfacename>NamespaceHandler</interfacename></title>
<para>In addition to the schema, we need a <interfacename>NamespaceHandler</interfacename>
that will parse all elements of this specific namespace Spring encounters
while parsing configuration files. The <interfacename>NamespaceHandler</interfacename>
should in our case take care of the parsing of the <literal>myns:dateformat</literal>
element.</para>
<para>The <interfacename>NamespaceHandler</interfacename> interface is pretty simple in that
it features just three methods:</para>
<itemizedlist spacing="compact">
<listitem>
<para><methodname>init()</methodname> - allows for initialization of
the <interfacename>NamespaceHandler</interfacename> and will be called by Spring
before the handler is used</para>
</listitem>
<listitem>
<para><methodname>BeanDefinition parse(Element, ParserContext)</methodname> -
called when Spring encounters a top-level element (not nested inside a bean definition
or a different namespace). This method can register bean definitions itself and/or
return a bean definition.</para>
</listitem>
<listitem>
<para><methodname>BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)</methodname> -
called when Spring encounters an attribute or nested element of a different namespace.
The decoration of one or more bean definitions is used for example with the
<link linkend="beans-factory-scopes">out-of-the-box scopes Spring 2.0 supports</link>.
We'll start by highlighting a simple example, without using decoration, after which
we will show decoration in a somewhat more advanced example.</para>
</listitem>
</itemizedlist>
<para>Although it is perfectly possible to code your own
<interfacename>NamespaceHandler</interfacename> for the entire namespace
(and hence provide code that parses each and every element in the namespace),
it is often the case that each top-level XML element in a Spring XML
configuration file results in a single bean definition (as in our
case, where a single <literal>&lt;myns:dateformat/&gt;</literal> element
results in a single <classname>SimpleDateFormat</classname> bean definition).
Spring features a number of convenience classes that support this scenario.
In this example, we'll make use the <classname>NamespaceHandlerSupport</classname> class:</para>
<programlisting language="java"><![CDATA[package org.springframework.samples.xml;
<note>
<para>The schema-based approach to creating configuration format allows for
tight integration with an IDE that has a schema-aware XML editor. Using a properly
authored schema, you can use autocompletion to have a user choose between several
configuration options defined in the enumeration.</para>
</note>
</section>
<section xml:id="extensible-xml-namespacehandler">
<title>Coding a <interfacename>NamespaceHandler</interfacename></title>
<para>In addition to the schema, we need a <interfacename>NamespaceHandler</interfacename>
that will parse all elements of this specific namespace Spring encounters
while parsing configuration files. The <interfacename>NamespaceHandler</interfacename>
should in our case take care of the parsing of the <literal>myns:dateformat</literal>
element.</para>
<para>The <interfacename>NamespaceHandler</interfacename> interface is pretty simple in that
it features just three methods:</para>
<itemizedlist spacing="compact">
<listitem>
<para><methodname>init()</methodname> - allows for initialization of
the <interfacename>NamespaceHandler</interfacename> and will be called by Spring
before the handler is used</para>
</listitem>
<listitem>
<para><methodname>BeanDefinition parse(Element, ParserContext)</methodname> -
called when Spring encounters a top-level element (not nested inside a bean definition
or a different namespace). This method can register bean definitions itself and/or
return a bean definition.</para>
</listitem>
<listitem>
<para><methodname>BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)</methodname> -
called when Spring encounters an attribute or nested element of a different namespace.
The decoration of one or more bean definitions is used for example with the
<link linkend="beans-factory-scopes">out-of-the-box scopes Spring 2.0 supports</link>.
We'll start by highlighting a simple example, without using decoration, after which
we will show decoration in a somewhat more advanced example.</para>
</listitem>
</itemizedlist>
<para>Although it is perfectly possible to code your own
<interfacename>NamespaceHandler</interfacename> for the entire namespace
(and hence provide code that parses each and every element in the namespace),
it is often the case that each top-level XML element in a Spring XML
configuration file results in a single bean definition (as in our
case, where a single <literal>&lt;myns:dateformat/&gt;</literal> element
results in a single <classname>SimpleDateFormat</classname> bean definition).
Spring features a number of convenience classes that support this scenario.
In this example, we'll make use the <classname>NamespaceHandlerSupport</classname> class:</para>
<programlisting language="java"><![CDATA[package org.springframework.samples.xml;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MyNamespaceHandler extends NamespaceHandlerSupport {
public void init() {]]><emphasis role="bold"><![CDATA[
registerBeanDefinitionParser("dateformat", new SimpleDateFormatBeanDefinitionParser());
registerBeanDefinitionParser("dateformat", new SimpleDateFormatBeanDefinitionParser());
]]></emphasis>}
}</programlisting>
<para>The observant reader will notice that there isn't actually a whole lot of
@@ -165,17 +169,17 @@ public class MyNamespaceHandler extends NamespaceHandlerSupport {
while delegating to <literal>BeanDefinitionParsers</literal> to do the grunt work of the
XML parsing; this means that each <interfacename>BeanDefinitionParser</interfacename> will
contain just the logic for parsing a single custom element, as we can see in the next step</para>
</section>
<section id="extensible-xml-parser">
<title>Coding a <interfacename>BeanDefinitionParser</interfacename></title>
<para>A <interfacename>BeanDefinitionParser</interfacename> will be used if the
<interfacename>NamespaceHandler</interfacename> encounters an XML element of the type
that has been mapped to the specific bean definition parser (which is <literal>'dateformat'</literal>
in this case). In other words, the <interfacename>BeanDefinitionParser</interfacename> is
responsible for parsing <emphasis>one</emphasis> distinct top-level XML element defined in the
schema. In the parser, we'll have access to the XML element (and thus its subelements too)
so that we can parse our custom XML content, as can be seen in the following example:</para>
<programlisting language="java"><![CDATA[package org.springframework.samples.xml;
</section>
<section xml:id="extensible-xml-parser">
<title>Coding a <interfacename>BeanDefinitionParser</interfacename></title>
<para>A <interfacename>BeanDefinitionParser</interfacename> will be used if the
<interfacename>NamespaceHandler</interfacename> encounters an XML element of the type
that has been mapped to the specific bean definition parser (which is <literal>'dateformat'</literal>
in this case). In other words, the <interfacename>BeanDefinitionParser</interfacename> is
responsible for parsing <emphasis>one</emphasis> distinct top-level XML element defined in the
schema. In the parser, we'll have access to the XML element (and thus its subelements too)
so that we can parse our custom XML content, as can be seen in the following example:</para>
<programlisting language="java"><![CDATA[package org.springframework.samples.xml;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
@@ -184,10 +188,10 @@ import org.w3c.dom.Element;
import java.text.SimpleDateFormat;
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { ]]><co id="extensible-xml-parser-simpledateformat-co-1"/><![CDATA[
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { ]]><co xml:id="extensible-xml-parser-simpledateformat-co-1"/><![CDATA[
protected Class getBeanClass(Element element) {
return SimpleDateFormat.class; ]]><co id="extensible-xml-parser-simpledateformat-co-2"/><![CDATA[
return SimpleDateFormat.class; ]]><co xml:id="extensible-xml-parser-simpledateformat-co-2"/><![CDATA[
}
protected void doParse(Element element, BeanDefinitionBuilder bean) {
@@ -202,66 +206,66 @@ public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefi
}
}
}]]></programlisting>
<calloutlist>
<callout arearefs="extensible-xml-parser-simpledateformat-co-1">
<para>We use the Spring-provided <classname>AbstractSingleBeanDefinitionParser</classname>
to handle a lot of the basic grunt work of creating a <emphasis>single</emphasis>
<interfacename>BeanDefinition</interfacename>.</para>
</callout>
<callout arearefs="extensible-xml-parser-simpledateformat-co-2">
<para>We supply the <classname>AbstractSingleBeanDefinitionParser</classname> superclass
with the type that our single <interfacename>BeanDefinition</interfacename> will represent.</para>
</callout>
</calloutlist>
<para>In this simple case, this is all that we need to do. The creation of our single
<interfacename>BeanDefinition</interfacename> is handled by the <classname>AbstractSingleBeanDefinitionParser</classname>
superclass, as is the extraction and setting of the bean definition's unique identifier.</para>
</section>
<section id="extensible-xml-registration">
<title>Registering the handler and the schema</title>
<para>The coding is finished! All that remains to be done is to somehow make the Spring XML
parsing infrastructure aware of our custom element; we do this by registering our custom
<interfacename>namespaceHandler</interfacename> and custom XSD file in two special purpose
properties files. These properties files are both placed in a
<filename class="directory">'META-INF'</filename> directory in your application, and can, for
example, be distributed alongside your binary classes in a JAR file. The Spring XML parsing
infrastructure will automatically pick up your new extension by consuming these special
properties files, the formats of which are detailed below.</para>
<section id="extensible-xml-registration-spring-handlers">
<title><filename>'META-INF/spring.handlers'</filename></title>
<para>The properties file called <filename>'spring.handlers'</filename> contains a mapping
of XML Schema URIs to namespace handler classes. So for our example, we need to write the
following:</para>
<programlisting><![CDATA[http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler]]></programlisting>
<para><emphasis>(The <literal>':'</literal> character is a valid delimiter in the Java properties format,
and so the <literal>':'</literal> character in the URI needs to be escaped with a backslash.)</emphasis></para>
<para>The first part (the key) of the key-value pair is the URI associated with your custom namespace
extension, and needs to <emphasis>match exactly</emphasis> the value of the
<literal>'targetNamespace'</literal> attribute as specified in your custom XSD schema.</para>
</section>
<section id="extensible-xml-registration-spring-schemas">
<title><filename>'META-INF/spring.schemas'</filename></title>
<para>The properties file called <filename>'spring.schemas'</filename> contains a mapping
of XML Schema locations (referred to along with the schema declaration in XML files
that use the schema as part of the <literal>'xsi:schemaLocation'</literal> attribute)
to <emphasis>classpath</emphasis> resources. This file is needed to prevent Spring from
absolutely having to use a default <interfacename>EntityResolver</interfacename> that requires
Internet access to retrieve the schema file. If you specify the mapping in this properties file,
Spring will search for the schema on the classpath (in this case <literal>'myns.xsd'</literal>
in the <literal>'org.springframework.samples.xml'</literal> package):</para>
<programlisting><![CDATA[http\://www.mycompany.com/schema/myns/myns.xsd=org/springframework/samples/xml/myns.xsd]]></programlisting>
<para>The upshot of this is that you are encouraged to deploy your XSD file(s) right alongside
the <interfacename>NamespaceHandler</interfacename> and <interfacename>BeanDefinitionParser</interfacename>
classes on the classpath.</para>
</section>
</section>
<section id="extensible-xml-using">
<title>Using a custom extension in your Spring XML configuration</title>
<para>Using a custom extension that you yourself have implemented is no different from
using one of the 'custom' extensions that Spring provides straight out of the box. Find below
an example of using the custom <literal>&lt;dateformat/&gt;</literal> element developed in the
previous steps in a Spring XML configuration file.</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<calloutlist>
<callout arearefs="extensible-xml-parser-simpledateformat-co-1">
<para>We use the Spring-provided <classname>AbstractSingleBeanDefinitionParser</classname>
to handle a lot of the basic grunt work of creating a <emphasis>single</emphasis>
<interfacename>BeanDefinition</interfacename>.</para>
</callout>
<callout arearefs="extensible-xml-parser-simpledateformat-co-2">
<para>We supply the <classname>AbstractSingleBeanDefinitionParser</classname> superclass
with the type that our single <interfacename>BeanDefinition</interfacename> will represent.</para>
</callout>
</calloutlist>
<para>In this simple case, this is all that we need to do. The creation of our single
<interfacename>BeanDefinition</interfacename> is handled by the <classname>AbstractSingleBeanDefinitionParser</classname>
superclass, as is the extraction and setting of the bean definition's unique identifier.</para>
</section>
<section xml:id="extensible-xml-registration">
<title>Registering the handler and the schema</title>
<para>The coding is finished! All that remains to be done is to somehow make the Spring XML
parsing infrastructure aware of our custom element; we do this by registering our custom
<interfacename>namespaceHandler</interfacename> and custom XSD file in two special purpose
properties files. These properties files are both placed in a
<filename class="directory">'META-INF'</filename> directory in your application, and can, for
example, be distributed alongside your binary classes in a JAR file. The Spring XML parsing
infrastructure will automatically pick up your new extension by consuming these special
properties files, the formats of which are detailed below.</para>
<section xml:id="extensible-xml-registration-spring-handlers">
<title><filename>'META-INF/spring.handlers'</filename></title>
<para>The properties file called <filename>'spring.handlers'</filename> contains a mapping
of XML Schema URIs to namespace handler classes. So for our example, we need to write the
following:</para>
<programlisting><![CDATA[http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler]]></programlisting>
<para><emphasis>(The <literal>':'</literal> character is a valid delimiter in the Java properties format,
and so the <literal>':'</literal> character in the URI needs to be escaped with a backslash.)</emphasis></para>
<para>The first part (the key) of the key-value pair is the URI associated with your custom namespace
extension, and needs to <emphasis>match exactly</emphasis> the value of the
<literal>'targetNamespace'</literal> attribute as specified in your custom XSD schema.</para>
</section>
<section xml:id="extensible-xml-registration-spring-schemas">
<title><filename>'META-INF/spring.schemas'</filename></title>
<para>The properties file called <filename>'spring.schemas'</filename> contains a mapping
of XML Schema locations (referred to along with the schema declaration in XML files
that use the schema as part of the <literal>'xsi:schemaLocation'</literal> attribute)
to <emphasis>classpath</emphasis> resources. This file is needed to prevent Spring from
absolutely having to use a default <interfacename>EntityResolver</interfacename> that requires
Internet access to retrieve the schema file. If you specify the mapping in this properties file,
Spring will search for the schema on the classpath (in this case <literal>'myns.xsd'</literal>
in the <literal>'org.springframework.samples.xml'</literal> package):</para>
<programlisting><![CDATA[http\://www.mycompany.com/schema/myns/myns.xsd=org/springframework/samples/xml/myns.xsd]]></programlisting>
<para>The upshot of this is that you are encouraged to deploy your XSD file(s) right alongside
the <interfacename>NamespaceHandler</interfacename> and <interfacename>BeanDefinitionParser</interfacename>
classes on the classpath.</para>
</section>
</section>
<section xml:id="extensible-xml-using">
<title>Using a custom extension in your Spring XML configuration</title>
<para>Using a custom extension that you yourself have implemented is no different from
using one of the 'custom' extensions that Spring provides straight out of the box. Find below
an example of using the custom <literal>&lt;dateformat/&gt;</literal> element developed in the
previous steps in a Spring XML configuration file.</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:myns="http://www.mycompany.com/schema/myns"
@@ -280,15 +284,15 @@ http://www.mycompany.com/schema/myns http://www.mycompany.com/schema/myns/myns.x
</bean>
</beans>]]></programlisting>
</section>
<section id="extensible-xml-meat">
<title>Meatier examples</title>
<para>Find below some much meatier examples of custom XML extensions.</para>
<section id="extensible-xml-custom-nested">
<title>Nesting custom tags within custom tags</title>
<para>This example illustrates how you might go about writing the various artifacts
required to satisfy a target of the following configuration:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
</section>
<section xml:id="extensible-xml-meat">
<title>Meatier examples</title>
<para>Find below some much meatier examples of custom XML extensions.</para>
<section xml:id="extensible-xml-custom-nested">
<title>Nesting custom tags within custom tags</title>
<para>This example illustrates how you might go about writing the various artifacts
required to satisfy a target of the following configuration:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:foo="http://www.foo.com/schema/component"
@@ -322,7 +326,7 @@ public class Component {
private String name;
private List<Component> components = new ArrayList<Component> ();
]]><lineannotation>// mmm, there is no setter method for the <literal>'components'</literal></lineannotation><![CDATA[
]]><lineannotation>// mmm, there is no setter method for the 'components'</lineannotation><![CDATA[
public void addComponent(Component component) {
this.components.add(component);
}
@@ -434,11 +438,11 @@ public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
return parseComponentElement(element);
}
private static AbstractBeanDefinition parseComponentElement(Element element) {
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ComponentFactoryBean.class);
factory.addPropertyValue("parent", parseComponent(element));
List<Element> childElements = DomUtils.getChildElementsByTagName(element, "component");
if (childElements != null && childElements.size() > 0) {
parseChildComponents(childElements, factory);
@@ -452,36 +456,36 @@ public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser
component.addPropertyValue("name", element.getAttribute("name"));
return component.getBeanDefinition();
}
private static void parseChildComponents(List<Element> childElements, BeanDefinitionBuilder factory) {
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>(childElements.size());
for (Element element : childElements) {
children.add(parseComponentElement(element));
}
factory.addPropertyValue("children", children);
}
}]]></programlisting>
<para>Lastly, the various artifacts need to be registered with the Spring XML infrastructure.</para>
<programlisting><lineannotation># in <filename>'META-INF/spring.handlers'</filename></lineannotation><![CDATA[
<programlisting><lineannotation># in 'META-INF/spring.handlers'</lineannotation><![CDATA[
http\://www.foo.com/schema/component=com.foo.ComponentNamespaceHandler]]></programlisting>
<programlisting><lineannotation># in <filename>'META-INF/spring.schemas'</filename></lineannotation><![CDATA[
<programlisting><lineannotation># in 'META-INF/spring.schemas'</lineannotation><![CDATA[
http\://www.foo.com/schema/component/component.xsd=com/foo/component.xsd]]></programlisting>
</section>
<section id="extensible-xml-custom-just-attributes">
<title>Custom attributes on 'normal' elements</title>
<para>Writing your own custom parser and the associated artifacts isn't hard, but sometimes it
is not the right thing to do. Consider the scenario where you need to add metadata to already
existing bean definitions. In this case you certainly don't want to have to go off and write
your own entire custom extension; rather you just want to add an additional attribute
to the existing bean definition element.</para>
<para>By way of another example, let's say that the service class that you are defining a bean
definition for a service object that will (unknown to it) be accessing a clustered
<ulink url="http://jcp.org/en/jsr/detail?id=107">JCache</ulink>, and you want to ensure that
the named JCache instance is eagerly started within the surrounding cluster:</para>
<programlisting language="xml"><![CDATA[<bean id="checkingAccountService" class="com.foo.DefaultCheckingAccountService"
]]><lineannotation><emphasis role="bold">jcache:cache-name="checking.account"&gt;</emphasis></lineannotation><![CDATA[
</section>
<section xml:id="extensible-xml-custom-just-attributes">
<title>Custom attributes on 'normal' elements</title>
<para>Writing your own custom parser and the associated artifacts isn't hard, but sometimes it
is not the right thing to do. Consider the scenario where you need to add metadata to already
existing bean definitions. In this case you certainly don't want to have to go off and write
your own entire custom extension; rather you just want to add an additional attribute
to the existing bean definition element.</para>
<para>By way of another example, let's say that the service class that you are defining a bean
definition for a service object that will (unknown to it) be accessing a clustered
<link xl:href="http://jcp.org/en/jsr/detail?id=107">JCache</link>, and you want to ensure that
the named JCache instance is eagerly started within the surrounding cluster:</para>
<programlisting language="xml"><![CDATA[<bean id="checkingAccountService" class="com.foo.DefaultCheckingAccountService"
]]><lineannotation>jcache:cache-name="checking.account"&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- other dependencies here... --&gt;</lineannotation><![CDATA[
</bean>]]></programlisting>
<para>What we are going to do here is create another <interfacename>BeanDefinition</interfacename>
@@ -548,7 +552,7 @@ import java.util.Arrays;
import java.util.List;
public class JCacheInitializingBeanDefinitionDecorator implements BeanDefinitionDecorator {
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public BeanDefinitionHolder decorate(
@@ -584,23 +588,23 @@ public class JCacheInitializingBeanDefinitionDecorator implements BeanDefinition
}
]]></programlisting>
<para>Lastly, the various artifacts need to be registered with the Spring XML infrastructure.</para>
<programlisting><lineannotation># in <filename>'META-INF/spring.handlers'</filename></lineannotation><![CDATA[
<programlisting><lineannotation># in 'META-INF/spring.handlers'</lineannotation><![CDATA[
http\://www.foo.com/schema/jcache=com.foo.JCacheNamespaceHandler]]></programlisting>
<programlisting><lineannotation># in <filename>'META-INF/spring.schemas'</filename></lineannotation><![CDATA[
<programlisting><lineannotation># in 'META-INF/spring.schemas'</lineannotation><![CDATA[
http\://www.foo.com/schema/jcache/jcache.xsd=com/foo/jcache.xsd]]></programlisting>
</section>
</section>
<section id="extensible-xml-resources">
<title>Further Resources</title>
<para>Find below links to further resources concerning XML Schema and the extensible XML support
described in this chapter.</para>
<itemizedlist>
<listitem>
<para>The <ulink url="http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/">XML Schema Part 1: Structures Second Edition</ulink></para>
</listitem>
<listitem>
<para>The <ulink url="http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/">XML Schema Part 2: Datatypes Second Edition</ulink></para>
</listitem>
</itemizedlist>
</section>
</section>
</section>
<section xml:id="extensible-xml-resources">
<title>Further Resources</title>
<para>Find below links to further resources concerning XML Schema and the extensible XML support
described in this chapter.</para>
<itemizedlist>
<listitem>
<para>The <link xl:href="http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/">XML Schema Part 1: Structures Second Edition</link></para>
</listitem>
<listitem>
<para>The <link xl:href="http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/">XML Schema Part 2: Datatypes Second Edition</link></para>
</listitem>
</itemizedlist>
</section>
</appendix>

View File

@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
<appendix xml:id="xsd-config"
xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="xsd-config">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
<title>XML Schema-based configuration</title>
<section id="xsd-config-introduction">
<section xml:id="xsd-config-introduction">
<title>Introduction</title>
<para>This appendix details the XML Schema-based configuration introduced in Spring 2.0 and enhanced and extended in Spring 2.5 and 3.0.</para>
<sidebar>
@@ -46,9 +50,9 @@
configuration tags that would better represent your application's domain; the process
involved in doing so is covered in the appendix entitled <xref linkend="extensible-xml"/>.</para>
</section>
<section id="xsd-config-body">
<section xml:id="xsd-config-body">
<title>XML Schema-based configuration</title>
<section id="xsd-config-body-referencing">
<section xml:id="xsd-config-body-referencing">
<title>Referencing the schemas</title>
<para>To switch over from the DTD-style to the new XML Schema-style, you need
to make the following change.</para>
@@ -84,14 +88,14 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
take advantage of the new Spring 2.0 XML tags since they make configuration easier. The
section entitled <xref linkend="xsd-config-body-schemas-util"/> demonstrates how you can
start immediately by using some of the more common utility tags.</para>
<para>The rest of this chapter is devoted to showing examples of the new Spring XML Schema
based configuration, with at least one example for every new tag. The format follows
a before and after style, with a <emphasis>before</emphasis> snippet of XML showing
the old (but still 100% legal and supported) style, followed immediately
by an <emphasis>after</emphasis> example showing the equivalent in the new XML Schema-based
style.</para>
</section>
<para>The rest of this chapter is devoted to showing examples of the new Spring XML Schema
based configuration, with at least one example for every new tag. The format follows
a before and after style, with a <emphasis>before</emphasis> snippet of XML showing
the old (but still 100% legal and supported) style, followed immediately
by an <emphasis>after</emphasis> example showing the equivalent in the new XML Schema-based
style.</para>
<section id="xsd-config-body-schemas-util">
<section xml:id="xsd-config-body-schemas-util">
<title>The <literal>util</literal> schema</title>
<para>First up is coverage of the <literal>util</literal> tags. As the name
implies, the <literal>util</literal> tags deal with common, <emphasis>utility</emphasis>
@@ -112,7 +116,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
]]><lineannotation>&lt;!-- bean definitions here --&gt;</lineannotation><![CDATA[
</beans>]]></programlisting>
<section id="xsd-config-body-schemas-util-constant">
<section xml:id="xsd-config-body-schemas-util-constant">
<title><literal>&lt;util:constant/&gt;</literal></title>
<para>Before...</para>
<programlisting language="xml"><![CDATA[<bean id="..." class="...">
@@ -137,10 +141,10 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</property>
</bean>]]></programlisting>
<section id="xsd-config-body-schemas-util-frfb">
<section xml:id="xsd-config-body-schemas-util-frfb">
<title>Setting a bean property or constructor arg from a field value</title>
<para>
<ulink url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html"><classname>FieldRetrievingFactoryBean</classname></ulink>
<link xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html"><classname>FieldRetrievingFactoryBean</classname></link>
is a <interfacename>FactoryBean</interfacename> which retrieves a
<literal>static</literal> or non-static field value. It is typically
used for retrieving <literal>public</literal> <literal>static</literal>
@@ -149,7 +153,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</para>
<para>
Find below an example which shows how a <literal>static</literal> field is exposed, by
using the <ulink url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)"><literal>staticField</literal></ulink>
using the <link xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)"><literal>staticField</literal></link>
property:
</para>
<programlisting language="xml"><![CDATA[<bean id="myField"
@@ -176,7 +180,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<para>
It is also possible to access a non-static (instance) field of another bean,
as described in the API documentation for the
<ulink url="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html"><classname>FieldRetrievingFactoryBean</classname></ulink>
<link xl:href="http://static.springframework.org/spring/docs/current/api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html"><classname>FieldRetrievingFactoryBean</classname></link>
class.
</para>
<para>
@@ -216,7 +220,7 @@ public class Client {
</para>
</section>
</section>
<section id="xsd-config-body-schemas-util-property-path">
<section xml:id="xsd-config-body-schemas-util-property-path">
<title><literal>&lt;util:property-path/&gt;</literal></title>
<para>Before...</para>
<programlisting language="xml"><lineannotation>&lt;!-- target bean to be referenced by name --&gt;</lineannotation><![CDATA[
@@ -252,7 +256,7 @@ public class Client {
<util:property-path id="name" path="testBean.age"/>]]></programlisting>
<para>The value of the <literal>'path'</literal> attribute of the
<literal>&lt;property-path/&gt;</literal> tag follows the form <literal>'beanName.beanProperty'</literal>.</para>
<section id="xsd-config-body-schemas-util-property-path-dependency">
<section xml:id="xsd-config-body-schemas-util-property-path-dependency">
<title>Using <literal>&lt;util:property-path/&gt;</literal> to set a bean property or constructor-argument</title>
<para><classname>PropertyPathFactoryBean</classname> is a
<interfacename>FactoryBean</interfacename> that evaluates a property path on a given
@@ -306,10 +310,10 @@ public class Client {
Please see the Javadocs for more info on this feature.</para>
</section>
</section>
<section id="xsd-config-body-schemas-util-properties">
<section xml:id="xsd-config-body-schemas-util-properties">
<title><literal>&lt;util:properties/&gt;</literal></title>
<para>Before...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.Properties</classname> instance with values loaded from the supplied location --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.Properties instance with values loaded from the supplied location --&gt;</lineannotation><![CDATA[
<bean id="jdbcConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>]]></programlisting>
@@ -319,13 +323,13 @@ public class Client {
the supplied <link linkend="resources"><interfacename>Resource</interfacename></link> location).
</para>
<para>After...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.Properties</classname> instance with values loaded from the supplied location --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.Properties instance with values loaded from the supplied location --&gt;</lineannotation><![CDATA[
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-util-list">
<section xml:id="xsd-config-body-schemas-util-list">
<title><literal>&lt;util:list/&gt;</literal></title>
<para>Before...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.List</classname> instance with values loaded from the supplied <literal>'sourceList'</literal> --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' --&gt;</lineannotation><![CDATA[
<bean id="emails" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
@@ -342,7 +346,7 @@ public class Client {
with values taken from the supplied <literal>'sourceList'</literal>.
</para>
<para>After...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.List</classname> instance with the supplied values --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.List instance with the supplied values --&gt;</lineannotation><![CDATA[
<util:list id="emails">
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
@@ -369,10 +373,10 @@ public class Client {
<xref linkend="beans-collection-elements-merging"/>.</para>
-->
</section>
<section id="xsd-config-body-schemas-util-map">
<section xml:id="xsd-config-body-schemas-util-map">
<title><literal>&lt;util:map/&gt;</literal></title>
<para>Before...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.Map</classname> instance with values loaded from the supplied <literal>'sourceMap'</literal> --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' --&gt;</lineannotation><![CDATA[
<bean id="emails" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
@@ -389,7 +393,7 @@ public class Client {
with key-value pairs taken from the supplied <literal>'sourceMap'</literal>.
</para>
<para>After...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.Map</classname> instance with the supplied key-value pairs --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.Map instance with the supplied key-value pairs --&gt;</lineannotation><![CDATA[
<util:map id="emails">
<entry key="pechorin" value="pechorin@hero.org"/>
<entry key="raskolnikov" value="raskolnikov@slums.org"/>
@@ -416,10 +420,10 @@ public class Client {
<xref linkend="beans-collection-elements-merging"/>.</para>
-->
</section>
<section id="xsd-config-body-schemas-util-set">
<section xml:id="xsd-config-body-schemas-util-set">
<title><literal>&lt;util:set/&gt;</literal></title>
<para>Before...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.Set</classname> instance with values loaded from the supplied <literal>'sourceSet'</literal> --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' --&gt;</lineannotation><![CDATA[
<bean id="emails" class="org.springframework.beans.factory.config.SetFactoryBean">
<property name="sourceSet">
<set>
@@ -436,7 +440,7 @@ public class Client {
with values taken from the supplied <literal>'sourceSet'</literal>.
</para>
<para>After...</para>
<programlisting language="xml"><lineannotation>&lt;!-- creates a <classname>java.util.Set</classname> instance with the supplied values --&gt;</lineannotation><![CDATA[
<programlisting language="xml"><lineannotation>&lt;!-- creates a java.util.Set instance with the supplied values --&gt;</lineannotation><![CDATA[
<util:set id="emails">
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
@@ -464,7 +468,7 @@ public class Client {
-->
</section>
</section>
<section id="xsd-config-body-schemas-jee">
<section xml:id="xsd-config-body-schemas-jee">
<title>The <literal>jee</literal> schema</title>
<para>The <literal>jee</literal> tags deal with Java EE (Java Enterprise Edition)-related
configuration issues, such as looking up a JNDI object and defining EJB references.</para>
@@ -483,7 +487,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
]]><lineannotation>&lt;!-- bean definitions here --&gt;</lineannotation><![CDATA[
</beans>]]></programlisting>
<section id="xsd-config-body-schemas-jee-jndi-lookup">
<section xml:id="xsd-config-body-schemas-jee-jndi-lookup">
<title><literal>&lt;jee:jndi-lookup/&gt;</literal> (simple)</title>
<para>Before...</para>
<programlisting language="xml"><![CDATA[<bean id="]]><emphasis role="bold"><![CDATA[dataSource]]></emphasis><![CDATA[" class="org.springframework.jndi.JndiObjectFactoryBean">
@@ -502,7 +506,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<property name="dataSource" ref="]]><emphasis role="bold">dataSource</emphasis>"/><![CDATA[
</bean>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jee-jndi-lookup-environment-single">
<section xml:id="xsd-config-body-schemas-jee-jndi-lookup-environment-single">
<title><literal>&lt;jee:jndi-lookup/&gt;</literal> (with single JNDI environment setting)</title>
<para>Before...</para>
<programlisting language="xml"><![CDATA[<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
@@ -518,7 +522,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<jee:environment>foo=bar</jee:environment>
</jee:jndi-lookup>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jee-jndi-lookup-evironment-multiple">
<section xml:id="xsd-config-body-schemas-jee-jndi-lookup-evironment-multiple">
<title><literal>&lt;jee:jndi-lookup/&gt;</literal> (with multiple JNDI environment settings)</title>
<para>Before...</para>
<programlisting language="xml"><![CDATA[<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
@@ -532,14 +536,14 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</bean>]]></programlisting>
<para>After...</para>
<programlisting language="xml"><![CDATA[<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource">
]]><lineannotation>&lt;!-- newline-separated, key-value pairs for the environment (standard <classname>Properties</classname> format) --&gt;</lineannotation><![CDATA[
]]><lineannotation>&lt;!-- newline-separated, key-value pairs for the environment (standard Properties format) --&gt;</lineannotation><![CDATA[
<jee:environment>
foo=bar
ping=pong
</jee:environment>
</jee:jndi-lookup>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jee-jndi-lookup-complex">
<section xml:id="xsd-config-body-schemas-jee-jndi-lookup-complex">
<title><literal>&lt;jee:jndi-lookup/&gt;</literal> (complex)</title>
<para>Before...</para>
<programlisting language="xml"><![CDATA[<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
@@ -559,7 +563,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
expected-type="com.myapp.DefaultFoo"
proxy-interface="com.myapp.Foo"/>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jee-local-slsb">
<section xml:id="xsd-config-body-schemas-jee-local-slsb">
<title><literal>&lt;jee:local-slsb/&gt;</literal> (simple)</title>
<para>The <literal>&lt;jee:local-slsb/&gt;</literal> tag configures a
reference to an EJB Stateless SessionBean.</para>
@@ -573,7 +577,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<programlisting language="xml"><![CDATA[<jee:local-slsb id="simpleSlsb" jndi-name="ejb/RentalServiceBean"
business-interface="com.foo.service.RentalService"/>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jee-local-slsb-complex">
<section xml:id="xsd-config-body-schemas-jee-local-slsb-complex">
<title><literal>&lt;jee:local-slsb/&gt;</literal> (complex)</title>
<programlisting language="xml"><![CDATA[<bean id="complexLocalEjb"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
@@ -591,7 +595,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
lookup-home-on-startup="true"
resource-ref="true">]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jee-remote-slsb">
<section xml:id="xsd-config-body-schemas-jee-remote-slsb">
<title><literal>&lt;jee:remote-slsb/&gt;</literal></title>
<para>The <literal>&lt;jee:remote-slsb/&gt;</literal> tag configures a
reference to a <literal>remote</literal> EJB Stateless SessionBean.</para>
@@ -617,7 +621,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
refresh-home-on-connect-failure="true">]]></programlisting>
</section>
</section>
<section id="xsd-config-body-schemas-lang">
<section xml:id="xsd-config-body-schemas-lang">
<title>The <literal>lang</literal> schema</title>
<para>The <literal>lang</literal> tags deal with exposing objects that have been
written in a dynamic language such as JRuby or Groovy as beans in the Spring
@@ -643,7 +647,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</beans>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-jms">
<section xml:id="xsd-config-body-schemas-jms">
<title>The <literal>jms</literal> schema</title>
<para>The <literal>jms</literal> tags deal with configuring JMS-related
beans such as Spring's <link linkend="jms-mdp">MessageListenerContainers</link>.
@@ -668,7 +672,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</beans>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-tx">
<section xml:id="xsd-config-body-schemas-tx">
<title>The <literal>tx</literal> (transaction) schema</title>
<para>The <literal>tx</literal> tags deal with configuring all of those
beans in Spring's comprehensive support for transactions. These tags are
@@ -708,7 +712,7 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/
so that the tags in the <literal>aop</literal> namespace are available to you.</para>
</note>
</section>
<section id="xsd-config-body-schemas-aop">
<section xml:id="xsd-config-body-schemas-aop">
<title>The <literal>aop</literal> schema</title>
<para>The <literal>aop</literal> tags deal with configuring all things
AOP in Spring: this includes Spring's own proxy-based AOP framework and Spring's
@@ -732,7 +736,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</beans>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-context">
<section xml:id="xsd-config-body-schemas-context">
<title>The <literal>context</literal> schema</title>
<para>The <literal>context</literal> tags deal with <interfacename>ApplicationContext</interfacename>
configuration that relates to plumbing - that is, not usually beans that are important to an end-user
@@ -753,7 +757,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
<note>
<para>The <literal>context</literal> schema was only introduced in Spring 2.5.</para>
</note>
<section id="xsd-config-body-schemas-context-pphc">
<section xml:id="xsd-config-body-schemas-context-pphc">
<title><literal>&lt;property-placeholder/&gt;</literal></title>
<para>This element activates the replacement of <literal>${...}</literal> placeholders, resolved
against the specified properties file (as a <link linkend="resources">Spring resource location</link>).
@@ -762,7 +766,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
for you; if you need more control over the <classname>PropertyPlaceholderConfigurer</classname>, just
define one yourself explicitly.</para>
</section>
<section id="xsd-config-body-schemas-context-ac">
<section xml:id="xsd-config-body-schemas-context-ac">
<title><literal>&lt;annotation-config/&gt;</literal></title>
<para>Activates the Spring infrastructure for various annotations to be detected in bean classes:
Spring's <link linkend="beans-required-annotation"><interfacename>@Required</interfacename></link>
@@ -780,25 +784,25 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
for that purpose.</para>
</note>
</section>
<section id="xsd-config-body-schemas-context-component-scan">
<section xml:id="xsd-config-body-schemas-context-component-scan">
<title><literal>&lt;component-scan/&gt;</literal></title>
<para>This element is detailed in <xref linkend="beans-annotation-config"/>.</para>
</section>
<section id="xsd-config-body-schemas-context-ltw">
<section xml:id="xsd-config-body-schemas-context-ltw">
<title><literal>&lt;load-time-weaver/&gt;</literal></title>
<para>This element is detailed in <xref linkend="aop-aj-ltw"/>.</para>
</section>
<section id="xsd-config-body-schemas-context-sc">
<section xml:id="xsd-config-body-schemas-context-sc">
<title><literal>&lt;spring-configured/&gt;</literal></title>
<para>This element is detailed in <xref linkend="aop-atconfigurable"/>.</para>
</section>
<section id="xsd-config-body-schemas-context-mbe">
<section xml:id="xsd-config-body-schemas-context-mbe">
<title><literal>&lt;mbean-export/&gt;</literal></title>
<para>This element is detailed in <xref linkend="jmx-context-mbeanexport"/>.</para>
</section>
</section>
<section id="xsd-config-body-schemas-tool">
<section xml:id="xsd-config-body-schemas-tool">
<title>The <literal>tool</literal> schema</title>
<para>The <literal>tool</literal> tags are for use when you want to add
tooling-specific metadata to your custom configuration elements. This metadata
@@ -813,7 +817,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
Spring source distribution.</para>
</section>
<section id="xsd-config-body-schemas-jdbc">
<section xml:id="xsd-config-body-schemas-jdbc">
<title>The <literal>jdbc</literal> schema</title>
<para>The <literal>jdbc</literal> tags allow you to quickly configure an
embedded database or initialize an existing data source. These tags are
@@ -837,7 +841,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</beans>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-cache">
<section xml:id="xsd-config-body-schemas-cache">
<title>The <literal>cache</literal> schema</title>
<para>The <literal>cache</literal> tags can be used to enable support for Spring's
<interfacename>@CacheEvict</interfacename>, <interfacename>@CachePut</interfacename>
@@ -862,7 +866,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</beans>]]></programlisting>
</section>
<section id="xsd-config-body-schemas-beans">
<section xml:id="xsd-config-body-schemas-beans">
<title>The <literal>beans</literal> schema</title>
<para>Last but not least we have the tags in the <literal>beans</literal> schema.
These are the same tags that have been in Spring since the very dawn of the framework.
@@ -896,20 +900,20 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
</section>
</section>
<!-- Commented pending resolution of SPR-7521
<section id="xsd-config-setup">
<section xml:id="xsd-config-setup">
<title>Setting up your IDE</title>
<para>This final section documents the steps involved in setting up a number of
popular Java IDEs to effect the easier editing of Spring's XML Schema-based
configuration files. If your favourite Java IDE or editor is not included in the
list of documented IDEs, then please do
<ulink url="http://opensource.atlassian.com/projects/spring/secure/Dashboard.jspa">raise an issue</ulink>
<link xl:href="http://opensource.atlassian.com/projects/spring/secure/Dashboard.jspa">raise an issue</link>
and an example with your favorite IDE/editor <emphasis>may</emphasis> be included
in the next release.</para>
<section id="xsd-config-setup-eclipse">
<section xml:id="xsd-config-setup-eclipse">
<title>Setting up Eclipse</title>
<procedure>
<para>The following steps illustrate setting up
<ulink url="http://www.eclipse.org/">Eclipse</ulink> to be XSD-aware.
<link xl:href="http://www.eclipse.org/">Eclipse</link> to be XSD-aware.
The assumption in the following steps is that you already have an Eclipse
project open (either a brand new project or an already existing one).</para>
<note>
@@ -965,7 +969,7 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
<para>The Eclipse Web Tools Platform (WTP)</para>
</entry>
<entry>
<ulink url="http://www.eclipse.org/webtools/"/>
<link xl:href="http://www.eclipse.org/webtools/"/>
</entry>
</row>
<row>
@@ -973,7 +977,7 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
<para>A list of Eclipse XML plugins</para>
</entry>
<entry>
<ulink url="http://eclipse-plugins.2y.net/eclipse/plugins.jsp?category=XML"/>
<link xl:href="http://eclipse-plugins.2y.net/eclipse/plugins.jsp?category=XML"/>
</entry>
</row>
</tbody>
@@ -984,7 +988,7 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
<para>Patches showing how to configure an Eclipse XML editor are
welcomed. Any such contributions are best submitted as patches via
the Spring Framework
<ulink url="http://opensource.atlassian.com/projects/spring/secure/Dashboard.jspa">JIRA Issue Tracker</ulink>
<link xl:href="http://opensource.atlassian.com/projects/spring/secure/Dashboard.jspa">JIRA Issue Tracker</link>
and <emphasis>may</emphasis> be featured in the next release.</para>
</sidebar>
<para>Unfortunately, precisely because there is no standard XML editor for Eclipse,
@@ -997,11 +1001,11 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
<step>
<title>Spring IDE</title>
<para>There is a dedicated Spring Framework plugin for Eclipse called
<ulink url="http://springide.org/blog/">Spring IDE</ulink> and it is pretty darn cool. (There's a
<link xl:href="http://springide.org/blog/">Spring IDE</link> and it is pretty darn cool. (There's a
considered and non-biased opinion for you!) This plugin makes using Spring even easier, and it has more
than just support for the core Spring Framework... Spring Web Flow is supported too. Details of how to
install Spring IDE can be found on the
<ulink url="http://springide.org/project/wiki/SpringideInstall">Spring IDE installation page</ulink>.</para>
<link xl:href="http://springide.org/project/wiki/SpringideInstall">Spring IDE installation page</link>.</para>
<para>
<mediaobject>
<imageobject role="fo">
@@ -1032,11 +1036,11 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
</step>
</procedure>
</section>
<section id="xsd-config-setup-idea">
<section xml:id="xsd-config-setup-idea">
<title>Setting up IntelliJ IDEA</title>
<procedure>
<para>The following steps illustrate setting up the
<ulink url="http://www.jetbrains.com/idea/">IntelliJ IDEA</ulink> IDE to be XSD-aware.
<link xl:href="http://www.jetbrains.com/idea/">IntelliJ IDEA</link> IDE to be XSD-aware.
The assumption in the following steps is that you already have an IDEA project
open (either a brand new project or an already existing one).</para>
<step>
@@ -1169,7 +1173,7 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
</procedure>
</section>
<section id="xsd-config-integration">
<section xml:id="xsd-config-integration">
<title>Integration issues</title>
<para>This final section details integration issues that may arise when you switch over
to using the above XSD-style for Spring 2.0 and later configuration.</para>
@@ -1177,14 +1181,14 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema
It has been included in the Spring documentation as a convenience to Spring users
so that if you encounter an issue when switching over to the XSD-style in some
specific environment you can refer to this section for the authoritative answer.</para>
<section id="xsd-config-integration-resin">
<section xml:id="xsd-config-integration-resin">
<title>XML parsing errors in the Resin v.3 application server</title>
<para>If you are using the XSD-style for Spring 2.0 XML configuration
and deploying to v.3 of Caucho's Resin application server, you will need
to set some configuration options prior to startup so that an XSD-aware
parser is available to Spring.</para>
<para>Please do read this resource,
<ulink url="http://www.caucho.com/resin-3.0/xml/jaxp.xtp#xerces">http://www.caucho.com/resin-3.0/xml/jaxp.xtp#xerces</ulink>,
<link xl:href="http://www.caucho.com/resin-3.0/xml/jaxp.xtp#xerces">http://www.caucho.com/resin-3.0/xml/jaxp.xtp#xerces</link>,
for further details.</para>
</section>
</section>