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:
@@ -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"><bean id="settersAndAbsquatulatePointcut"
|
||||
<para><programlisting language="xml"><bean id="settersAndAbsquatulatePointcut"
|
||||
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
|
||||
<property name="patterns">
|
||||
<list>
|
||||
@@ -191,7 +195,7 @@
|
||||
the one bean encapsulates both pointcut and advice, as shown
|
||||
below:</para>
|
||||
|
||||
<para><programlisting language="xml"><bean id="settersAndAbsquatulateAdvisor"
|
||||
<para><programlisting language="xml"><bean id="settersAndAbsquatulateAdvisor"
|
||||
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
|
||||
<property name="advice">
|
||||
<ref local="beanNameOfAopAllianceInterceptor"/>
|
||||
@@ -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 {
|
||||
<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor">
|
||||
</bean>
|
||||
|
||||
<bean id="person"
|
||||
<bean id="person"
|
||||
class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces" value="com.mycompany.Person"/>
|
||||
|
||||
@@ -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"><bean id="transactionManager"
|
||||
<programlisting language="xml"><bean id="transactionManager"
|
||||
class="org.springframework.transaction.jta.JtaTransactionManager"/></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"><bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject"
|
||||
<para><programlisting language="xml"><bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject"
|
||||
scope="prototype">
|
||||
... properties omitted
|
||||
</bean>
|
||||
@@ -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
@@ -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 @@
|
||||
|
||||
</beans></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><context:annotation-config/></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 {
|
||||
</beans></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>
|
||||
|
||||
|
||||
@@ -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 {
|
||||
</beans></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
|
||||
|
||||
@@ -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"><beans>
|
||||
|
||||
<lineannotation><!-- this <interfacename>MessageSource</interfacename> is being used in a web application --></lineannotation>
|
||||
<lineannotation><!-- this MessageSource is being used in a web application --></lineannotation>
|
||||
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
|
||||
<property name="basename" value="exceptions"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!-- lets inject the above <interfacename>MessageSource</interfacename> into this POJO --></lineannotation>
|
||||
<lineannotation><!-- lets inject the above MessageSource into this POJO --></lineannotation>
|
||||
<bean id="example" class="com.foo.Example">
|
||||
<property name="messages" ref="messageSource"/>
|
||||
</bean>
|
||||
@@ -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.</
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<lineannotation><!-- or use the <classname>ContextLoaderServlet</classname> instead of the above listener</lineannotation><emphasis>
|
||||
<lineannotation><!-- or use the ContextLoaderServlet instead of the above listener</lineannotation><emphasis>
|
||||
<servlet>
|
||||
<servlet-name>context</servlet-name>
|
||||
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 {
|
||||
</bean></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"><bean id="exampleBean" class="examples.ExampleBean">
|
||||
|
||||
<lineannotation><!-- setter injection using the nested <literal><ref/></literal> element --></lineannotation>
|
||||
<lineannotation><!-- setter injection using the nested <ref/> element --></lineannotation>
|
||||
<property name="beanOne"><ref bean="anotherExampleBean"/></property>
|
||||
|
||||
<lineannotation><!-- setter injection using the neater 'ref' attribute --></lineannotation>
|
||||
@@ -416,7 +420,7 @@ public class ExampleBean {
|
||||
|
||||
<programlisting language="xml"><bean id="exampleBean" class="examples.ExampleBean">
|
||||
|
||||
<lineannotation><!-- constructor injection using the nested <literal><ref/></literal> element --></lineannotation>
|
||||
<lineannotation><!-- constructor injection using the nested <ref/> element --></lineannotation>
|
||||
<constructor-arg>
|
||||
<ref bean="anotherExampleBean"/>
|
||||
</constructor-arg>
|
||||
@@ -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><constructor-arg/></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"><bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
|
||||
<lineannotation><!-- results in a <methodname>setDriverClassName(String)</methodname> call --></lineannotation>
|
||||
<lineannotation><!-- results in a setDriverClassName(String) call --></lineannotation>
|
||||
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
|
||||
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
|
||||
<property name="username" value="root"/>
|
||||
@@ -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"><bean id="mappings"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
|
||||
<lineannotation><!-- typed as a <classname>java.util.Properties</classname> --></lineannotation>
|
||||
<lineannotation><!-- typed as a java.util.Properties --></lineannotation>
|
||||
<property name="properties">
|
||||
<value>
|
||||
jdbc.driver.className=com.mysql.jdbc.Driver
|
||||
@@ -577,7 +581,7 @@ public class ExampleBean {
|
||||
favor the use of the nested <literal><value/></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"><property name="targetName">
|
||||
<lineannotation><!-- a bean with id '<literal>theTargetBean</literal>' must exist; otherwise an exception will be thrown --></lineannotation>
|
||||
<lineannotation><!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown --></lineannotation>
|
||||
<idref local="theTargetBean"/>
|
||||
</property></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 {
|
||||
</bean></programlisting>
|
||||
</section>
|
||||
|
||||
<section id="beans-inner-beans">
|
||||
<section xml:id="beans-inner-beans">
|
||||
<title>Inner beans</title>
|
||||
|
||||
<para>A <literal><bean/></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><list/></literal>,
|
||||
@@ -741,7 +745,7 @@ public class ExampleBean {
|
||||
<interfacename>Properties</interfacename>, respectively.</para>
|
||||
|
||||
<programlisting language="xml"><bean id="moreComplexObject" class="example.ComplexObject">
|
||||
<lineannotation><!-- results in a setAdminEmails(<classname>java.util.Properties</classname>) call --></lineannotation>
|
||||
<lineannotation><!-- results in a setAdminEmails(java.util.Properties) call --></lineannotation>
|
||||
<property name="adminEmails">
|
||||
<props>
|
||||
<prop key="administrator">administrator@example.org</prop>
|
||||
@@ -749,14 +753,14 @@ public class ExampleBean {
|
||||
<prop key="development">development@example.org</prop>
|
||||
</props>
|
||||
</property>
|
||||
<lineannotation><!-- results in a setSomeList(<interfacename>java.util.List</interfacename>) call --></lineannotation>
|
||||
<lineannotation><!-- results in a setSomeList(java.util.List) call --></lineannotation>
|
||||
<property name="someList">
|
||||
<list>
|
||||
<value>a list element followed by a reference</value>
|
||||
<ref bean="myDataSource" />
|
||||
</list>
|
||||
</property>
|
||||
<lineannotation><!-- results in a setSomeMap(<interfacename>java.util.Map</interfacename>) call --></lineannotation>
|
||||
<lineannotation><!-- results in a setSomeMap(java.util.Map) call --></lineannotation>
|
||||
<property name="someMap">
|
||||
<map>
|
||||
<entry key="an entry" value="just some string"/>
|
||||
@@ -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"><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">
|
||||
|
||||
|
||||
<bean id="bar" class="x.y.Bar"/>
|
||||
<bean id="baz" class="x.y.Baz"/>
|
||||
|
||||
<-- 'traditional' declaration -->
|
||||
<-- 'traditional' declaration -->
|
||||
<bean id="foo" class="x.y.Foo">
|
||||
<constructor-arg ref="bar"/>
|
||||
<constructor-arg ref="baz"/>
|
||||
@@ -1061,24 +1065,24 @@ support=support@example.co.uk</programlisting>
|
||||
|
||||
</beans></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"><-- 'c-namespace' index declaration -->
|
||||
<bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz"></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>
|
||||
</beans></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><!-- inject dependencies here as required --></lineannotation>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!-- <literal>commandProcessor</literal> uses <literal>statefulCommandHelper</literal> --></lineannotation>
|
||||
<lineannotation><!-- commandProcessor uses statefulCommandHelper --></lineannotation>
|
||||
<bean id="commandManager" class="fiona.apple.CommandManager">
|
||||
<lookup-method name="createCommand" bean="command"/>
|
||||
</bean></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 {
|
||||
|
||||
|
||||
@@ -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><!--
|
||||
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
|
||||
--></lineannotation>
|
||||
<bean class="scripting.InstantiationTracingBeanPostProcessor"/>
|
||||
|
||||
@@ -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><beans /></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>
|
||||
|
||||
|
||||
@@ -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<?>...)</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><import/></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><bean/></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><context:component-scan/></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 -> 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>
|
||||
|
||||
|
||||
@@ -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 @@
|
||||
<bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/></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><!-- using <literal>spring-beans-2.0.dtd</literal> --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- using spring-beans-2.0.dtd --></lineannotation>
|
||||
<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/></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">
|
||||
|
||||
<lineannotation><!-- an HTTP <interfacename>Session</interfacename>-scoped bean exposed as a proxy --></lineannotation>
|
||||
<lineannotation><!-- an HTTP Session-scoped bean exposed as a proxy --></lineannotation>
|
||||
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
|
||||
|
||||
<lineannotation><!-- instructs the container to proxy the surrounding bean --></lineannotation>
|
||||
@@ -413,7 +417,7 @@
|
||||
<lineannotation><!-- a singleton-scoped bean injected with a proxy to the above bean --></lineannotation>
|
||||
<bean id="userService" class="com.foo.SimpleUserService">
|
||||
|
||||
<lineannotation><!-- a reference to the proxied <literal>userPreferences</literal> bean --></lineannotation>
|
||||
<lineannotation><!-- a reference to the proxied userPreferences bean --></lineannotation>
|
||||
<property name="userPreferences" ref="userPreferences"/>
|
||||
|
||||
</bean>
|
||||
@@ -493,7 +497,7 @@
|
||||
<property name="userPreferences" ref="userPreferences"/>
|
||||
</bean></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><!-- <classname>DefaultUserPreferences</classname> implements the <interfacename>UserPreferences</interfacename> interface --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- DefaultUserPreferences implements the UserPreferences interface --></lineannotation>
|
||||
<bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session">
|
||||
<aop:scoped-proxy proxy-target-class="false"<literal/>/>
|
||||
</bean>
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
@@ -23,8 +27,8 @@
|
||||
<version>1</version>
|
||||
</dependency></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"><beans>
|
||||
<context:component-scan base-package="org.example"/>
|
||||
</beans></programlisting>
|
||||
</beans></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>—</entry>
|
||||
</row>
|
||||
</row>
|
||||
<row>
|
||||
<entry>@Value</entry>
|
||||
<entry>—</entry>
|
||||
<entry>no equivalent</entry>
|
||||
</row>
|
||||
</row>
|
||||
<row>
|
||||
<entry>@Required</entry>
|
||||
<entry>—</entry>
|
||||
<entry>no equivalent</entry>
|
||||
</row>
|
||||
</row>
|
||||
<row>
|
||||
<entry>@Lazy</entry>
|
||||
<entry>—</entry>
|
||||
<entry>no equivalent</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -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><!-- the factory bean, which contains a method called <methodname>createInstance()</methodname> --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- the factory bean, which contains a method called createInstance() --></lineannotation>
|
||||
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
|
||||
<lineannotation><!-- inject any dependencies required by this locator bean --></lineannotation>
|
||||
</bean>
|
||||
@@ -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();
|
||||
<bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
|
||||
parent="inheritedTestBeanWithoutClass" init-method="initialize">
|
||||
<property name="name" value="override"/>
|
||||
<lineannotation><!-- age will inherit the value of <literal>1</literal> from the parent bean definition--></lineannotation>
|
||||
<lineannotation><!-- age will inherit the value of 1 from the parent bean definition--></lineannotation>
|
||||
</bean></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
@@ -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 @@
|
||||
</bean></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
|
||||
</bean></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
@@ -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"><beans>
|
||||
|
||||
|
||||
<bean id="myProductDao" class="product.ProductDaoImpl">
|
||||
<property name="persistenceManagerFactory" ref="myPmf"/>
|
||||
</bean>
|
||||
|
||||
|
||||
</beans></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 @@
|
||||
</beans></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<String, String> params = new HashMap<String, String>();
|
||||
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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"><!--
|
||||
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:
|
||||
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
|
||||
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
|
||||
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
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).
|
||||
-->
|
||||
<!ELEMENT beans (
|
||||
description?,
|
||||
(import | alias | bean)*
|
||||
description?,
|
||||
(import | alias | bean)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST beans default-lazy-init (true | false) "false">
|
||||
<!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no">
|
||||
@@ -66,37 +70,37 @@
|
||||
<!ATTLIST beans default-merge (true | false) "false">
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT description (#PCDATA)>
|
||||
|
||||
|
||||
<!--
|
||||
Specifies an XML bean definition resource to import.
|
||||
Specifies an XML bean definition resource to import.
|
||||
-->
|
||||
<!ELEMENT import EMPTY>
|
||||
|
||||
<!--
|
||||
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".
|
||||
-->
|
||||
<!ATTLIST import resource CDATA #REQUIRED>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT alias EMPTY>
|
||||
|
||||
<!--
|
||||
The name of the bean to define an alias for.
|
||||
The name of the bean to define an alias for.
|
||||
-->
|
||||
<!ATTLIST alias name CDATA #REQUIRED>
|
||||
|
||||
<!--
|
||||
The alias name to define for the bean.
|
||||
The alias name to define for the bean.
|
||||
-->
|
||||
<!ATTLIST alias alias CDATA #REQUIRED>
|
||||
|
||||
@@ -116,97 +120,97 @@
|
||||
<!ATTLIST meta value CDATA #REQUIRED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT bean (
|
||||
description?,
|
||||
(meta | constructor-arg | property | lookup-method | replaced-method)*
|
||||
description?,
|
||||
(meta | constructor-arg | property | lookup-method | replaced-method)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
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).
|
||||
-->
|
||||
<!ATTLIST bean id ID #IMPLIED>
|
||||
|
||||
<!--
|
||||
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).
|
||||
-->
|
||||
<!ATTLIST bean name CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean class CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean parent CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean scope CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean abstract (true | false) #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean lazy-init (true | false | default) "default">
|
||||
|
||||
@@ -217,163 +221,163 @@
|
||||
<!ATTLIST bean autowire-candidate (true | false) #IMPLIED>
|
||||
|
||||
<!--
|
||||
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 <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 <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.
|
||||
-->
|
||||
<!ATTLIST bean autowire (no | byName | byType | constructor | autodetect | default) "default">
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean dependency-check (none | objects | simple | all | default) "default">
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean depends-on CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean init-method CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean destroy-method CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean factory-method CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST bean factory-bean CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT constructor-arg (
|
||||
description?,
|
||||
(bean | ref | idref | value | null | list | set | map | props)?
|
||||
description?,
|
||||
(bean | ref | idref | value | null | list | set | map | props)?
|
||||
)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST constructor-arg index CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST constructor-arg type CDATA #IMPLIED>
|
||||
|
||||
@@ -389,20 +393,20 @@
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT property (
|
||||
description?, meta*,
|
||||
(bean | ref | idref | value | null | list | set | map | props)?
|
||||
description?, meta*,
|
||||
(bean | ref | idref | value | null | list | set | map | props)?
|
||||
)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST property name CDATA #REQUIRED>
|
||||
|
||||
@@ -418,86 +422,86 @@
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT lookup-method EMPTY>
|
||||
|
||||
<!--
|
||||
Name of a lookup method. This method should take no arguments.
|
||||
Name of a lookup method. This method should take no arguments.
|
||||
-->
|
||||
<!ATTLIST lookup-method name CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST lookup-method bean CDATA #IMPLIED>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT replaced-method (
|
||||
(arg-type)*
|
||||
(arg-type)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST replaced-method name CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST replaced-method replacer CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT arg-type (#PCDATA)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST arg-type match CDATA #IMPLIED>
|
||||
|
||||
|
||||
<!--
|
||||
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).
|
||||
-->
|
||||
<!ELEMENT ref EMPTY>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST ref bean CDATA #IMPLIED>
|
||||
<!ATTLIST ref local IDREF #IMPLIED>
|
||||
@@ -505,132 +509,132 @@
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT idref EMPTY>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST idref bean CDATA #IMPLIED>
|
||||
<!ATTLIST idref local IDREF #IMPLIED>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT value (#PCDATA)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST value type CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT null (#PCDATA)>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT list (
|
||||
(bean | ref | idref | value | null | list | set | map | props)*
|
||||
(bean | ref | idref | value | null | list | set | map | props)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
-->
|
||||
<!ATTLIST list merge (true | false | default) "default">
|
||||
|
||||
<!--
|
||||
Specify the default Java type for nested values.
|
||||
Specify the default Java type for nested values.
|
||||
-->
|
||||
<!ATTLIST list value-type CDATA #IMPLIED>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT set (
|
||||
(bean | ref | idref | value | null | list | set | map | props)*
|
||||
(bean | ref | idref | value | null | list | set | map | props)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
-->
|
||||
<!ATTLIST set merge (true | false | default) "default">
|
||||
|
||||
<!--
|
||||
Specify the default Java type for nested values.
|
||||
Specify the default Java type for nested values.
|
||||
-->
|
||||
<!ATTLIST set value-type CDATA #IMPLIED>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT map (
|
||||
(entry)*
|
||||
(entry)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
-->
|
||||
<!ATTLIST map merge (true | false | default) "default">
|
||||
|
||||
<!--
|
||||
Specify the default Java type for nested entry keys.
|
||||
Specify the default Java type for nested entry keys.
|
||||
-->
|
||||
<!ATTLIST map key-type CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
Specify the default Java type for nested entry values.
|
||||
Specify the default Java type for nested entry values.
|
||||
-->
|
||||
<!ATTLIST map value-type CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT entry (
|
||||
key?,
|
||||
(bean | ref | idref | value | null | list | set | map | props)?
|
||||
(bean | ref | idref | value | null | list | set | map | props)?
|
||||
)>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ATTLIST entry key CDATA #IMPLIED>
|
||||
|
||||
@@ -650,35 +654,35 @@
|
||||
<!ATTLIST entry value-ref CDATA #IMPLIED>
|
||||
|
||||
<!--
|
||||
A key element can contain an inner bean, ref, value, or collection.
|
||||
A key element can contain an inner bean, ref, value, or collection.
|
||||
-->
|
||||
<!ELEMENT key (
|
||||
(bean | ref | idref | value | null | list | set | map | props)
|
||||
(bean | ref | idref | value | null | list | set | map | props)
|
||||
)>
|
||||
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT props (
|
||||
(prop)*
|
||||
(prop)*
|
||||
)>
|
||||
|
||||
<!--
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
Enable/disable merging for collections when using parent/child beans.
|
||||
-->
|
||||
<!ATTLIST props merge (true | false | default) "default">
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!ELEMENT prop (#PCDATA)>
|
||||
|
||||
<!--
|
||||
Each property element must specify its key.
|
||||
Each property element must specify its key.
|
||||
-->
|
||||
<!ATTLIST prop key CDATA #REQUIRED></programlisting></para>
|
||||
</appendix>
|
||||
|
||||
@@ -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 <<emphasis>insert your favourite dynamic language here</emphasis>>,
|
||||
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><!-- this is the bean definition for the Groovy-backed <interfacename>Messenger</interfacename> implementation --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- this is the bean definition for the Groovy-backed Messenger implementation --></lineannotation><![CDATA[
|
||||
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
|
||||
<lang:property name="message" value="I Can Do The Frug" />
|
||||
</lang:groovy>
|
||||
|
||||
]]><lineannotation><!-- an otherwise normal bean that will be injected by the Groovy-backed <interfacename>Messenger</interfacename> --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger --></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><lang:language/></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 < 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><!-- this next constructor argument will *not* be injected into the <classname>GroovyMessenger</classname> --></lineannotation>
|
||||
<lineannotation><!-- this next constructor argument will *not* be injected into the GroovyMessenger --></lineannotation>
|
||||
<lineannotation><!-- in fact, this isn't even allowed according to the schema --></lineannotation><![CDATA[
|
||||
<constructor-arg value="]]><lineannotation><emphasis role="bold">This will *not* work</emphasis></lineannotation><![CDATA[" />]]>
|
||||
|
||||
<lineannotation><!-- <emphasis role="bold">only</emphasis> property values are injected into the dynamic-language-backed object --></lineannotation><![CDATA[
|
||||
<constructor-arg value="]]><lineannotation>This will *not* work</lineannotation><![CDATA[" />]]>
|
||||
|
||||
<lineannotation><!-- only property values are injected into the dynamic-language-backed object --></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><!-- define the <interfacename>GroovyObjectCustomizer</interfacename> just like any other bean --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- define the GroovyObjectCustomizer just like any other bean --></lineannotation>
|
||||
<![CDATA[<bean id="tracingCustomizer" class="example.SimpleMethodTracingCustomizer" />
|
||||
|
||||
]]><lineannotation><!-- ... and plug it into the desired Groovy bean via the '<literal>customizer-ref</literal>' attribute --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- ... and plug it into the desired Groovy bean via the 'customizer-ref' attribute --></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><!-- define the <interfacename>GroovyObjectCustomizer</interfacename> (as an inner bean) --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- define the GroovyObjectCustomizer (as an inner bean) --></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>
|
||||
|
||||
|
||||
@@ -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. We’ll follow best practice and use the EJB Business Methods
|
||||
Interface pattern, so that the EJB’s local interface extends a non
|
||||
EJB-specific business methods interface. Let’s 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. We’ll follow best practice and use the EJB Business Methods
|
||||
Interface pattern, so that the EJB’s local interface extends a non
|
||||
EJB-specific business methods interface. Let’s 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 we’ll 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 we’ll 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 we’ll 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 we’ll 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>
|
||||
There’s a lot of work happening behind the scenes, courtesy of
|
||||
the Spring AOP framework, although you aren’t 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 there’s
|
||||
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>
|
||||
There’s a lot of work happening behind the scenes, courtesy of
|
||||
the Spring AOP framework, although you aren’t 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 there’s
|
||||
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><jee:local-slsb></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 haven’t 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 don’t want to make fine-grained calls
|
||||
to EJBs anyway, as there’s 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 haven’t 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 don’t want to make fine-grained calls
|
||||
to EJBs anyway, as there’s 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><jee:remote-slsb></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>
|
||||
|
||||
@@ -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<Boolean> booleanList = new ArrayList<Boolean>();
|
||||
}
|
||||
|
||||
|
||||
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>#{ <expression
|
||||
string> }</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);
|
||||
</bean></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' < '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 ('<'), gt ('>'), le ('<='), ge ('>='),
|
||||
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 < 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 > 10 from the list (using selection ?{...})
|
||||
// evaluates to [11, 13, 17]
|
||||
List<Integer> primesGreaterThanTen =
|
||||
List<Integer> primesGreaterThanTen =
|
||||
(List<Integer>) parser.parseExpression("#primes.?[#this>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<Integer> 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<Integer> primesGreaterThanTen =
|
||||
|
||||
public static String reverseString(String input) {
|
||||
StringBuilder backwards = new StringBuilder();
|
||||
for (int i = 0; i < input.length(); i++)
|
||||
for (int i = 0; i < input.length(); i++)
|
||||
backwards.append(input.charAt(input.length() - 1 - i));
|
||||
}
|
||||
return backwards.toString();
|
||||
@@ -898,19 +902,19 @@ List<Integer> 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<Inventor> list = (List<Inventor>)
|
||||
<programlisting language="java">List<Inventor> list = (List<Inventor>)
|
||||
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<Inventor> members = new ArrayList<Inventor>();
|
||||
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<Inventor> members = new ArrayList<Inventor>();
|
||||
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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<Actor> {
|
||||
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<Actor> {
|
||||
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<Actor> {
|
||||
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<Actor> {
|
||||
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<Actor> {
|
||||
<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<Actor> {
|
||||
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">
|
||||
|
||||
|
||||
<bean id="corporateEventDao" class="com.example.JdbcCorporateEventDao">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="${jdbc.driverClassName}"/>
|
||||
<property name="url" value="${jdbc.url}"/>
|
||||
@@ -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">
|
||||
|
||||
|
||||
<!-- Scans within the base package of the application for @Components to configure as beans -->
|
||||
<context:component-scan base-package="org.springframework.docs.test" />
|
||||
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="${jdbc.driverClassName}"/>
|
||||
<property name="url" value="${jdbc.url}"/>
|
||||
@@ -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<Actor> mapper = new RowMapper<Actor>() {
|
||||
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<Actor> mapper = new RowMapper<Actor>() {
|
||||
RowMapper<Actor> mapper = new RowMapper<Actor>() {
|
||||
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<Map<String, Object>> 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"><bean id="dataSource"
|
||||
<programlisting language="java"><bean id="dataSource"
|
||||
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="${jdbc.driverClassName}"/>
|
||||
<property name="url" value="${jdbc.url}"/>
|
||||
@@ -1160,7 +1165,7 @@ dataSource.setPassword("");</programlisting>
|
||||
<context:property-placeholder location="jdbc.properties"/></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<String, Object> results = execute(new HashMap<String, Object>());
|
||||
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<Title> {
|
||||
|
||||
|
||||
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<Genre> {
|
||||
|
||||
|
||||
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>
|
||||
|
||||
|
||||
@@ -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 {
|
||||
<bean class="jmsexample.DefaultTextMessageDelegate"/>
|
||||
</constructor-arg>
|
||||
<property name="defaultListenerMethod" value="receive"/>
|
||||
<lineannotation><!-- we <emphasis role="bold">don't</emphasis> want automatic message context extraction --></lineannotation>
|
||||
<lineannotation><!-- we don't want automatic message context extraction --></lineannotation>
|
||||
<property name="messageConverter">
|
||||
<null/>
|
||||
</property>
|
||||
@@ -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>>
|
||||
|
||||
<lineannotation><!-- <literal><bean/></literal> definitions here --></lineannotation>
|
||||
<lineannotation><!-- <bean/> definitions here --></lineannotation>
|
||||
|
||||
</beans></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><listener></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><listener-container></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><jca-listener-container/></literal> element</title>
|
||||
|
||||
|
||||
@@ -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><!-- this bean must <emphasis role="bold">not</emphasis> be lazily initialized if the exporting is to happen --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- this bean must not be lazily initialized if the exporting is to happen --></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><!--
|
||||
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
|
||||
--></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><!-- indicate to first look for a server --></lineannotation><![CDATA[
|
||||
<property name="locateExistingServerIfPossible" value="true"/>
|
||||
]]><lineannotation><!-- search for the <interfacename>MBeanServer</interfacename> instance with the given agentId --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- search for the MBeanServer instance with the given agentId --></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><!-- Custom <literal>MBeanServerLocator</literal> --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- Custom MBeanServerLocator --></lineannotation><![CDATA[
|
||||
<bean class="platform.package.MBeanServerLocator" factory-method="locateMBeanServer"/>
|
||||
</property>
|
||||
|
||||
|
||||
]]><lineannotation><!-- other beans here --></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><!-- will pick up the <classname>ObjectName</classname> from the annotation --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- will pick up the ObjectName from the annotation --></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><!-- notice how no <literal>'beans'</literal> are explicitly configured here --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- notice how no 'beans' are explicitly configured here --></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><!-- implements both the <interfacename>NotificationListener</interfacename> and <interfacename>NotificationFilter</interfacename> interfaces --></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>
|
||||
|
||||
@@ -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
@@ -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<E></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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"><beans>
|
||||
|
||||
<lineannotation><!-- <classname>Exception</classname> translation bean post processor --></lineannotation>
|
||||
<lineannotation><!-- Exception translation bean post processor --></lineannotation>
|
||||
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
|
||||
|
||||
<bean id="myProductDao" class="product.ProductDaoImpl"/>
|
||||
@@ -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">
|
||||
|
||||
<lineannotation><!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --></lineannotation>
|
||||
<lineannotation><!-- SessionFactory, DataSource, etc. omitted --></lineannotation>
|
||||
|
||||
<bean id="transactionManager"
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="productServiceMethods"
|
||||
<aop:pointcut id="productServiceMethods"
|
||||
expression="execution(* product.ProductService.*(..))"/>
|
||||
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
|
||||
</aop:config>
|
||||
@@ -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">
|
||||
|
||||
<lineannotation><!-- <interfacename>SessionFactory</interfacename>, <interfacename>DataSource</interfacename>, etc. omitted --></lineannotation>
|
||||
<lineannotation><!-- SessionFactory, DataSource, etc. omitted --></lineannotation>
|
||||
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<tx:annotation-driven/>
|
||||
|
||||
<bean id="myProductService" class="product.SimpleProductService">
|
||||
@@ -530,7 +534,7 @@ TR: REVISED, PLS REVIEW.-->This declarative transaction capability allows you
|
||||
</beans></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><jee:jndi-lookup></literal></literal>)
|
||||
<literal>JndiObjectFactoryBean</literal> or <literal><jee:jndi-lookup></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><jee:jndi-lookup></literal></literal> can be used to
|
||||
standard <literal>JndiObjectFactoryBean</literal> or
|
||||
<literal><jee:jndi-lookup></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">
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.jdo.JdoTransactionManager">
|
||||
@@ -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"><beans>
|
||||
|
||||
|
||||
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="dataSource" ref="someDataSource"/>
|
||||
<property name="loadTimeWeaver">
|
||||
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
</beans></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"><context:load-time-weaver/>
|
||||
|
||||
<programlisting language="xml"><context:load-time-weaver/>
|
||||
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
...
|
||||
</bean></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"><bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="loadTimeWeaver">
|
||||
@@ -1493,23 +1497,23 @@ TR: OK AS IS. The requirement is to provide the classloader for the runtime envi
|
||||
</bean></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">
|
||||
|
||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
@@ -1745,7 +1749,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --><!-- </para>
|
||||
<bean id="myProductService" class="product.ProductServiceImpl">
|
||||
<property name="productDao" ref="myProductDao"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
|
||||
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
|
||||
@@ -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
|
||||
</beans></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;
|
||||
}
|
||||
|
||||
@@ -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.*-<version>.jar</code>), and the
|
||||
dependencies are also in this "long" form, with external libraries
|
||||
(not from SpringSource) having the prefix
|
||||
<code>com.springsource</code>. See the <ulink security=""
|
||||
url="http://www.springsource.com/repository/app/faq">FAQ</ulink>
|
||||
<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><resolvers>
|
||||
|
||||
|
||||
<url name="com.springsource.repository.bundles.release">
|
||||
|
||||
<ivy pattern="http://repository.springsource.com/ivy/bundles/release/
|
||||
@@ -705,7 +709,7 @@ TR: OK. Added to diagram.--></para>
|
||||
<ivy pattern="http://repository.springsource.com/ivy/bundles/external/
|
||||
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
||||
<artifact pattern="http://repository.springsource.com/ivy/bundles/external/
|
||||
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
||||
[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
|
||||
|
||||
</url>
|
||||
|
||||
@@ -721,12 +725,12 @@ TR: OK. Added to diagram.--></para>
|
||||
include in your dependencies section. For example (in
|
||||
<filename>ivy.xml</filename>): </para>
|
||||
|
||||
<programlisting><dependency org="org.springframework"
|
||||
<programlisting><dependency org="org.springframework"
|
||||
name="org.springframework.core" rev="3.0.0.RELEASE" conf="compile->runtime"/></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><dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies> </programlisting>
|
||||
|
||||
<para>That might seem like a lot of dependencies just to get some
|
||||
logging. Well it is, but it <emphasis>is</emphasis> optional, and it
|
||||
should behave better than the vanilla <code>commons-logging</code> with
|
||||
respect to classloader issues, notably if you are in a strict container
|
||||
like an OSGi platform. Allegedly there is also a performance benefit
|
||||
because the bindings are at compile-time not runtime.</para>
|
||||
|
||||
<para>A more common choice amongst SLF4J users, which uses fewer steps
|
||||
and generates fewer dependencies, is to bind directly to <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><dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies> </programlisting>
|
||||
|
||||
<para>That might seem like a lot of dependencies just to get some
|
||||
logging. Well it is, but it <emphasis>is</emphasis> optional, and it
|
||||
should behave better than the vanilla <code>commons-logging</code> with
|
||||
respect to classloader issues, notably if you are in a strict container
|
||||
like an OSGi platform. Allegedly there is also a performance benefit
|
||||
because the bindings are at compile-time not runtime.</para>
|
||||
|
||||
<para>A more common choice amongst SLF4J users, which uses fewer steps
|
||||
and generates fewer dependencies, is to bind directly to <ulink type=""
|
||||
url="http://logback.qos.ch">Logback</ulink>. This removes the extra
|
||||
binding step because Logback implements SLF4J directly, so you only need
|
||||
to depend on two 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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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<Account> 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 {
|
||||
<property name="serviceName" value="AccountService"/>
|
||||
<property name="service" ref="accountService"/>
|
||||
<property name="serviceInterface" value="example.AccountService"/>
|
||||
<lineannotation><!-- defaults to <literal>1099</literal> --></lineannotation>
|
||||
<lineannotation><!-- defaults to 1099 --></lineannotation>
|
||||
<property name="registryPort" value="1199"/>
|
||||
</bean></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 {
|
||||
</servlet-mapping></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 {
|
||||
</bean></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 {
|
||||
<property name="interceptors" ref="authorizationInterceptor"/>
|
||||
</bean>
|
||||
|
||||
<bean id="authorizationInterceptor"
|
||||
<bean id="authorizationInterceptor"
|
||||
class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">
|
||||
<property name="authorizedRoles" value="administrator,operator"/>
|
||||
</bean></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"><bean name="accountExporter"
|
||||
<programlisting language="xml"><bean name="accountExporter"
|
||||
class="org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter">
|
||||
<property name="service" ref="accountService"/>
|
||||
<property name="serviceInterface" value="example.AccountService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="httpServer"
|
||||
<bean id="httpServer"
|
||||
class="org.springframework.remoting.support.SimpleHttpServerFactoryBean">
|
||||
<property name="contexts">
|
||||
<util:map>
|
||||
@@ -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
|
||||
</bean></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 {
|
||||
|
||||
</beans></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<T> 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<T> 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<String,String></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></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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/></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>
|
||||
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
<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">
|
||||
|
||||
<lineannotation><!-- this bean will be injected into the HibernateTitleRepositoryTests class --></lineannotation>
|
||||
@@ -2014,7 +2016,7 @@ public class HibernateTitleRepositoryTests {
|
||||
role="bold">com.foo.repository.hibernate.HibernateTitleRepository</emphasis>">
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="sessionFactory"
|
||||
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
|
||||
<lineannotation><!-- configuration elided for brevity --></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>
|
||||
|
||||
65
src/reference/docbook/titlepage/spring-html.xml
Normal file
65
src/reference/docbook/titlepage/spring-html.xml
Normal 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>
|
||||
101
src/reference/docbook/titlepage/spring-pdf.xml
Normal file
101
src/reference/docbook/titlepage/spring-pdf.xml
Normal 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>
|
||||
@@ -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">
|
||||
|
||||
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>
|
||||
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>
|
||||
|
||||
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
|
||||
|
||||
<lineannotation><!-- other <literal><bean/></literal> definitions here --></lineannotation>
|
||||
|
||||
<lineannotation><!-- other <bean/> definitions here --></lineannotation>
|
||||
|
||||
</beans></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><!-- from the file <literal>'context.xml'</literal> --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- from the file 'context.xml' --></lineannotation>
|
||||
<?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: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">
|
||||
|
||||
|
||||
<lineannotation><!-- this is the service object that we want to make transactional --></lineannotation>
|
||||
<bean id="fooService" class="x.y.service.DefaultFooService"/>
|
||||
|
||||
<lineannotation><!-- the transactional advice (what 'happens'; see the <literal><aop:advisor/></literal> bean below) --></lineannotation>
|
||||
<lineannotation><!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) --></lineannotation>
|
||||
<tx:advice id="txAdvice" transaction-manager="txManager">
|
||||
<lineannotation><!-- the transactional semantics... --></lineannotation>
|
||||
<tx:attributes>
|
||||
<lineannotation><!-- all methods starting with <literal>'get'</literal> are read-only --></lineannotation>
|
||||
<lineannotation><!-- all methods starting with 'get' are read-only --></lineannotation>
|
||||
<tx:method name="get*" read-only="true"/>
|
||||
<lineannotation><!-- other methods use the default transaction settings (see below) --></lineannotation>
|
||||
<tx:method name="*"/>
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
|
||||
<lineannotation><!-- ensure that the above transactional advice runs for any execution
|
||||
of an operation defined by the <interfacename>FooService</interfacename> interface --></lineannotation>
|
||||
of an operation defined by the FooService interface --></lineannotation>
|
||||
<aop:config>
|
||||
<aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
|
||||
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
|
||||
</aop:config>
|
||||
|
||||
<lineannotation><!-- don't forget the <interfacename>DataSource</interfacename> --></lineannotation>
|
||||
|
||||
<lineannotation><!-- don't forget the DataSource --></lineannotation>
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
|
||||
<property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
|
||||
@@ -835,12 +839,12 @@ public class DefaultFooService implements FooService {
|
||||
<property name="password" value="tiger"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!-- similarly, don't forget the <interfacename>PlatformTransactionManager</interfacename> --></lineannotation>
|
||||
<lineannotation><!-- similarly, don't forget the PlatformTransactionManager --></lineannotation>
|
||||
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!-- other <literal><bean/></literal> definitions here --></lineannotation>
|
||||
|
||||
<lineannotation><!-- other <bean/> definitions here --></lineannotation>
|
||||
|
||||
</beans></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"><!-- the Spring container is starting up... --></emphasis></lineannotation>
|
||||
<programlisting language="xml"> <lineannotation><!-- the Spring container is starting up... --></lineannotation>
|
||||
[AspectJInvocationContextExposingAdvisorAutoProxyCreator] - Creating implicit proxy
|
||||
for bean 'fooService' with 0 common interceptors and 1 specific interceptors
|
||||
<lineannotation><emphasis role="bold"><!-- the <classname>DefaultFooService</classname> is actually proxied --></emphasis></lineannotation>
|
||||
<lineannotation><!-- the DefaultFooService is actually proxied --></lineannotation>
|
||||
[JdkDynamicAopProxy] - Creating JDK dynamic proxy for [x.y.service.DefaultFooService]
|
||||
|
||||
<lineannotation><emphasis role="bold"><!-- ... the <literal>insertFoo(..)</literal> method is now being invoked on the proxy --></emphasis></lineannotation>
|
||||
<lineannotation><!-- ... the insertFoo(..) method is now being invoked on the proxy --></lineannotation>
|
||||
|
||||
[TransactionInterceptor] - Getting transaction for x.y.service.FooService.insertFoo
|
||||
<lineannotation><emphasis role="bold"><!-- the transactional advice kicks in here... --></emphasis></lineannotation>
|
||||
<lineannotation><!-- the transactional advice kicks in here... --></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"><!-- the <literal>insertFoo(..)</literal> method from <classname>DefaultFooService</classname> throws an exception... --></emphasis></lineannotation>
|
||||
<lineannotation><!-- the insertFoo(..) method from DefaultFooService throws an exception... --></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"><!-- and the transaction is rolled back (by default, <exceptionname>RuntimeException</exceptionname> instances cause rollback) --></emphasis></lineannotation>
|
||||
<lineannotation><!-- and the transaction is rolled back (by default, RuntimeException instances cause rollback) --></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"><!-- AOP infrastructure stack trace elements removed for clarity --></emphasis></lineannotation>
|
||||
<lineannotation><!-- AOP infrastructure stack trace elements removed for clarity --></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"><tx:advice id="txAdvice" transaction-manager="txManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="get*" read-only="true" <lineannotation><emphasis
|
||||
role="bold">rollback-for="NoProductInStockException"</emphasis></lineannotation>/>
|
||||
<tx:method name="get*" read-only="true" <lineannotation>rollback-for="NoProductInStockException"</lineannotation>/>
|
||||
<tx:method name="*"/>
|
||||
</tx:attributes>
|
||||
</tx:advice></programlisting>
|
||||
@@ -1021,7 +1024,7 @@ if the underlying application server infrastructure throws an Error the transact
|
||||
|
||||
<programlisting language="xml"><tx:advice id="txAdvice">
|
||||
<tx:attributes>
|
||||
<tx:method name="updateStock" <lineannotation><emphasis role="bold">no-rollback-for="InstrumentNotFoundException"</emphasis></lineannotation>/>
|
||||
<tx:method name="updateStock" <lineannotation>no-rollback-for="InstrumentNotFoundException"</lineannotation>/>
|
||||
<tx:method name="*"/>
|
||||
</tx:attributes>
|
||||
</tx:advice></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">
|
||||
|
||||
<aop:config>
|
||||
@@ -1115,7 +1118,7 @@ if the underlying application server infrastructure throws an Error the transact
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
<lineannotation><!-- other transaction infrastructure beans such as a <interfacename>PlatformTransactionManager</interfacename> omitted... --></lineannotation>
|
||||
<lineannotation><!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --></lineannotation>
|
||||
|
||||
</beans></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">
|
||||
|
||||
<aop:config>
|
||||
@@ -1149,7 +1152,7 @@ if the underlying application server infrastructure throws an Error the transact
|
||||
|
||||
</aop:config>
|
||||
|
||||
<lineannotation><!-- this bean will be transactional (see the <literal>'defaultServiceOperation'</literal> pointcut) --></lineannotation>
|
||||
<lineannotation><!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) --></lineannotation>
|
||||
<bean id="fooService" class="x.y.service.DefaultFooService"/>
|
||||
|
||||
<lineannotation><!-- this bean will also be transactional, but with totally different transactional settings --></lineannotation>
|
||||
@@ -1168,12 +1171,12 @@ if the underlying application server infrastructure throws an Error the transact
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
<lineannotation><!-- other transaction infrastructure beans such as a <interfacename>PlatformTransactionManager</interfacename> omitted... --></lineannotation>
|
||||
<lineannotation><!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --></lineannotation>
|
||||
|
||||
</beans></programlisting>
|
||||
</section>
|
||||
|
||||
<section id="transaction-declarative-txadvice-settings">
|
||||
<section xml:id="transaction-declarative-txadvice-settings">
|
||||
<title><literal><tx:advice/></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><tx:attributes/></literal> tags are summarized
|
||||
below:</para>
|
||||
|
||||
<para><table id="tx-method-settings">
|
||||
<para><table xml:id="tx-method-settings">
|
||||
<title><literal><tx:method/></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><!-- from the file <literal>'context.xml'</literal> --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- from the file 'context.xml' --></lineannotation>
|
||||
<?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: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">
|
||||
|
||||
|
||||
<lineannotation><!-- this is the service object that we want to make transactional --></lineannotation>
|
||||
<bean id="fooService" class="x.y.service.DefaultFooService"/>
|
||||
|
||||
<lineannotation><!-- enable the configuration of transactional behavior based on annotations --></lineannotation>
|
||||
<emphasis role="bold"><tx:annotation-driven transaction-manager="txManager"/></emphasis>
|
||||
|
||||
<lineannotation><!-- a <interfacename>PlatformTransactionManager</interfacename> is still required --></lineannotation>
|
||||
<lineannotation><!-- a PlatformTransactionManager is still required --></lineannotation>
|
||||
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<lineannotation><!-- (this dependency is defined somewhere else) --></lineannotation>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!-- other <literal><bean/></literal> definitions here --></lineannotation>
|
||||
|
||||
<lineannotation><!-- other <bean/> definitions here --></lineannotation>
|
||||
|
||||
</beans></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><tx:annotation-driven></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><tx:annotation-driven></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">
|
||||
|
||||
<bean id="fooService" class="x.y.service.DefaultFooService"/>
|
||||
@@ -2051,7 +2054,7 @@ public class SimpleProfiler implements Ordered {
|
||||
role="bold">order="200"</emphasis>/>
|
||||
|
||||
<aop:config>
|
||||
<lineannotation><!-- this advice will execute <emphasis role="bold">around</emphasis> the transactional advice --></lineannotation>
|
||||
<lineannotation><!-- this advice will execute around the transactional advice --></lineannotation>
|
||||
<aop:aspect id="profilingAspect" ref="profiler">
|
||||
<aop:pointcut id="serviceMethodWithReturnValue"
|
||||
expression="execution(!void x.y..*Service.*(..))"/>
|
||||
@@ -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">
|
||||
|
||||
<bean id="fooService" class="x.y.service.DefaultFooService"/>
|
||||
@@ -2127,7 +2130,7 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
<lineannotation><!-- other <bean/> definitions such as a <interfacename>DataSource</interfacename> and a <interfacename>PlatformTransactionManager</interfacename> here --></lineannotation>
|
||||
<lineannotation><!-- other <bean/> definitions such as a DataSource and a PlatformTransactionManager here --></lineannotation>
|
||||
|
||||
</beans></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
|
||||
<property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
|
||||
<property name="timeout" value="30"/>
|
||||
</bean>"</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>
|
||||
|
||||
@@ -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 <T> 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 <T> 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 & 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>
|
||||
|
||||
@@ -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 & 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><!-- the <classname>ResourceBundleViewResolver</classname> --></lineannotation>
|
||||
<programlisting language="xml"><lineannotation><!-- the ResourceBundleViewResolver --></lineannotation>
|
||||
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
|
||||
<property name="basename" value="views"/>
|
||||
</bean>
|
||||
@@ -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>
|
||||
</form:form></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>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Subscribe to newsletter?:</td>
|
||||
<lineannotation><%-- Approach 1: Property is of type <classname>java.lang.Boolean</classname> --%></lineannotation>
|
||||
<lineannotation><%-- Approach 1: Property is of type java.lang.Boolean --%></lineannotation>
|
||||
<td><form:checkbox path="preferences.receiveNewsletter"/></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Interests:</td>
|
||||
<td>
|
||||
<lineannotation><%-- Approach 2: Property is of an array or of type <interfacename>java.util.Collection</interfacename> --%></lineannotation>
|
||||
<lineannotation><%-- Approach 2: Property is of an array or of type java.util.Collection --%></lineannotation>
|
||||
Quidditch: <form:checkbox path="preferences.interests" value="Quidditch"/>
|
||||
Herbology: <form:checkbox path="preferences.interests" value="Herbology"/>
|
||||
Defence Against the Dark Arts: <form:checkbox path="preferences.interests"
|
||||
@@ -304,7 +308,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp</programlisting>
|
||||
<tr>
|
||||
<td>Favourite Word:</td>
|
||||
<td>
|
||||
<lineannotation><%-- Approach 3: Property is of type <classname>java.lang.Object</classname> --%></lineannotation>
|
||||
<lineannotation><%-- Approach 3: Property is of type java.lang.Object --%></lineannotation>
|
||||
Magic: <form:checkbox path="preferences.favouriteWord" value="Magic"/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -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>
|
||||
<tr>
|
||||
<td>Interests:</td>
|
||||
<td>
|
||||
<lineannotation><%-- Property is of an array or of type <interfacename>java.util.Collection</interfacename> --%></lineannotation>
|
||||
<lineannotation><%-- Property is of an array or of type java.util.Collection --%></lineannotation>
|
||||
<form:checkboxes path="preferences.interests" items="${interestList}"/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -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>
|
||||
</tr></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>
|
||||
</tr></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>
|
||||
</tr></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>
|
||||
</tr></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>
|
||||
</tr></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>
|
||||
</tr></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>
|
||||
</form></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) {
|
||||
</bean></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 & 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><!--
|
||||
<programlisting language="xml"><lineannotation><!--
|
||||
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
|
||||
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!--
|
||||
<lineannotation><!--
|
||||
|
||||
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
|
||||
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
|
||||
</bean>
|
||||
|
||||
<lineannotation><!--
|
||||
<lineannotation><!--
|
||||
|
||||
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
|
||||
</property>
|
||||
</bean></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
|
||||
<html>
|
||||
...
|
||||
<form action="" method="POST">
|
||||
Name:
|
||||
Name:
|
||||
#springBind( "command.name" )
|
||||
<input type="text"
|
||||
name="${status.expression}"
|
||||
<input type="text"
|
||||
name="${status.expression}"
|
||||
value="$!status.value" /><br>
|
||||
#foreach($error in $status.errorMessages) <b>$error</b> <br> #end
|
||||
<br>
|
||||
...
|
||||
...
|
||||
<input type="submit" value="submit"/>
|
||||
</form>
|
||||
...
|
||||
@@ -1245,14 +1249,14 @@ recommend sticking to 'spring' -->
|
||||
<html>
|
||||
...
|
||||
<form action="" method="POST">
|
||||
Name:
|
||||
<@spring.bind "command.name" />
|
||||
<input type="text"
|
||||
name="${spring.status.expression}"
|
||||
Name:
|
||||
<@spring.bind "command.name" />
|
||||
<input type="text"
|
||||
name="${spring.status.expression}"
|
||||
value="${spring.status.value?default("")}" /><br>
|
||||
<#list spring.status.errorMessages as error> <b>${error}</b> <br> </#list>
|
||||
<br>
|
||||
...
|
||||
...
|
||||
<input type="submit" value="submit"/>
|
||||
</form>
|
||||
...
|
||||
@@ -1278,7 +1282,7 @@ recommend sticking to 'spring' -->
|
||||
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' -->
|
||||
<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' -->
|
||||
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"><!-- the Name field example from above using form macros in VTL -->
|
||||
@@ -1550,7 +1554,7 @@ recommend sticking to 'spring' -->
|
||||
<para>The generated HTML looks like this:</para>
|
||||
|
||||
<programlisting>Name:
|
||||
<input type="text" name="name" value=""
|
||||
<input type="text" name="name" value=""
|
||||
>
|
||||
<br>
|
||||
<b>required</b>
|
||||
@@ -1563,7 +1567,7 @@ recommend sticking to 'spring' -->
|
||||
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' -->
|
||||
|
||||
<programlisting>Town:
|
||||
<input type="radio" name="address.town" value="London"
|
||||
|
||||
|
||||
>
|
||||
London
|
||||
<input type="radio" name="address.town" value="Paris"
|
||||
checked="checked"
|
||||
checked="checked"
|
||||
>
|
||||
Paris
|
||||
<input type="radio" name="address.town" value="New York"
|
||||
|
||||
|
||||
>
|
||||
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:
|
||||
<input type="radio" name="address.town" value="LDN"
|
||||
|
||||
|
||||
>
|
||||
London
|
||||
<input type="radio" name="address.town" value="PRS"
|
||||
checked="checked"
|
||||
checked="checked"
|
||||
>
|
||||
Paris
|
||||
<input type="radio" name="address.town" value="NYC"
|
||||
|
||||
|
||||
>
|
||||
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 < 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<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>
|
||||
|
||||
@@ -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>
|
||||
<context-param/> 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><faces-config/></literal> element, add an
|
||||
@@ -221,7 +225,7 @@
|
||||
</managed-bean></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 @@
|
||||
</faces-config></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 @@
|
||||
</faces-config></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&aid=1088866&group_id=39190&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&aid=1088866&group_id=39190&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"><bean name="/users" .../></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 <controller> element. These
|
||||
lines follow the <action-mapping> element.</para>
|
||||
@@ -432,21 +436,21 @@
|
||||
|
||||
<note>
|
||||
<para>If you are using Tiles in your Struts application, you must
|
||||
configure your <controller> with the <ulink
|
||||
url="http://static.springframework.org/spring/docs/current/api/org/springframework/web/struts/DelegatingTilesRequestProcessor.html"><classname>DelegatingTilesRequestProcessor</classname></ulink>
|
||||
configure your <controller> 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"><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>>
|
||||
|
||||
|
||||
<beans>
|
||||
<!-- the DataSource -->
|
||||
<jee:jndi-lookup id="dataSource" jndi-name="java:DefaultDS"/>
|
||||
|
||||
<bean id="hibSessionFactory"
|
||||
<bean id="hibSessionFactory"
|
||||
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager"
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.transaction.jta.JtaTransactionManager"/>
|
||||
|
||||
<bean id="mapper"
|
||||
<bean id="mapper"
|
||||
class="com.whatever.dataaccess.mapper.hibernate.MapperImpl">
|
||||
<property name="sessionFactory" ref="hibSessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<!-- (transactional) AuthenticationService -->
|
||||
<bean id="authenticationService"
|
||||
<bean id="authenticationService"
|
||||
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
<property name="target">
|
||||
@@ -693,10 +697,10 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
|
||||
*=PROPAGATION_REQUIRED
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</bean>
|
||||
|
||||
<!-- (transactional) UserService -->
|
||||
<bean id="userService"
|
||||
<bean id="userService"
|
||||
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
<property name="target">
|
||||
@@ -710,8 +714,8 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem
|
||||
*=PROPAGATION_REQUIRED
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</bean>
|
||||
|
||||
</beans></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>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE application PUBLIC
|
||||
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
|
||||
<!DOCTYPE application PUBLIC
|
||||
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
|
||||
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
|
||||
<application
|
||||
name="Whatever xPortal"
|
||||
@@ -816,7 +820,7 @@ public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
|
||||
</application></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"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE page-specification PUBLIC
|
||||
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
|
||||
<!DOCTYPE page-specification PUBLIC
|
||||
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
|
||||
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
|
||||
|
||||
|
||||
<page-specification class="com.whatever.web.xportal.pages.Login">
|
||||
|
||||
|
||||
<property-specification name="username" type="java.lang.String"/>
|
||||
<property-specification name="password" type="java.lang.String"/>
|
||||
<property-specification name="error" type="java.lang.String"/>
|
||||
@@ -856,31 +860,31 @@ public class MyEngine extends org.apache.tapestry.engine.BaseEngine {
|
||||
type="com.whatever.services.service.user.AuthenticationService">
|
||||
global.appContext.getBean("authenticationService")
|
||||
</property-specification>
|
||||
|
||||
|
||||
<bean name="delegate" class="com.whatever.web.xportal.PortalValidationDelegate"/>
|
||||
|
||||
|
||||
<bean name="validator" class="org.apache.tapestry.valid.StringValidator" lifecycle="page">
|
||||
<set-property name="required" expression="true"/>
|
||||
<set-property name="clientScriptingEnabled" expression="true"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<component id="inputUsername" type="ValidField">
|
||||
<static-binding name="displayName" value="Username"/>
|
||||
<binding name="value" expression="username"/>
|
||||
<binding name="validator" expression="beans.validator"/>
|
||||
</component>
|
||||
|
||||
|
||||
<component id="inputPassword" type="ValidField">
|
||||
<binding name="value" expression="password"/>
|
||||
<binding name="validator" expression="beans.validator"/>
|
||||
<static-binding name="displayName" value="Password"/>
|
||||
<binding name="hidden" expression="true"/>
|
||||
</component>
|
||||
|
||||
|
||||
</page-specification></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.
|
||||
* <p>
|
||||
* 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>
|
||||
|
||||
@@ -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><!-- myns.xsd (inside package org/springframework/samples/xml) --></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><!-- myns.xsd (inside package org/springframework/samples/xml) --></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><myns:dateformat/></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><myns:dateformat/></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><myns:dateformat/></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><myns:dateformat/></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><dateformat/></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><dateformat/></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"></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"></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- other dependencies here... --></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>
|
||||
|
||||
@@ -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><!-- bean definitions here --></lineannotation><![CDATA[
|
||||
|
||||
</beans>]]></programlisting>
|
||||
<section id="xsd-config-body-schemas-util-constant">
|
||||
<section xml:id="xsd-config-body-schemas-util-constant">
|
||||
<title><literal><util:constant/></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><util:property-path/></literal></title>
|
||||
<para>Before...</para>
|
||||
<programlisting language="xml"><lineannotation><!-- target bean to be referenced by name --></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><property-path/></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><util:property-path/></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><util:properties/></literal></title>
|
||||
<para>Before...</para>
|
||||
<programlisting language="xml"><lineannotation><!-- creates a <classname>java.util.Properties</classname> instance with values loaded from the supplied location --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.Properties instance with values loaded from the supplied location --></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><!-- creates a <classname>java.util.Properties</classname> instance with values loaded from the supplied location --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.Properties instance with values loaded from the supplied location --></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><util:list/></literal></title>
|
||||
<para>Before...</para>
|
||||
<programlisting language="xml"><lineannotation><!-- creates a <classname>java.util.List</classname> instance with values loaded from the supplied <literal>'sourceList'</literal> --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' --></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><!-- creates a <classname>java.util.List</classname> instance with the supplied values --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.List instance with the supplied values --></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><util:map/></literal></title>
|
||||
<para>Before...</para>
|
||||
<programlisting language="xml"><lineannotation><!-- creates a <classname>java.util.Map</classname> instance with values loaded from the supplied <literal>'sourceMap'</literal> --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' --></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><!-- creates a <classname>java.util.Map</classname> instance with the supplied key-value pairs --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.Map instance with the supplied key-value pairs --></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><util:set/></literal></title>
|
||||
<para>Before...</para>
|
||||
<programlisting language="xml"><lineannotation><!-- creates a <classname>java.util.Set</classname> instance with values loaded from the supplied <literal>'sourceSet'</literal> --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' --></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><!-- creates a <classname>java.util.Set</classname> instance with the supplied values --></lineannotation><![CDATA[
|
||||
<programlisting language="xml"><lineannotation><!-- creates a java.util.Set instance with the supplied values --></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><!-- bean definitions here --></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><jee:jndi-lookup/></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><jee:jndi-lookup/></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><jee:jndi-lookup/></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><!-- newline-separated, key-value pairs for the environment (standard <classname>Properties</classname> format) --></lineannotation><![CDATA[
|
||||
]]><lineannotation><!-- newline-separated, key-value pairs for the environment (standard Properties format) --></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><jee:jndi-lookup/></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><jee:local-slsb/></literal> (simple)</title>
|
||||
<para>The <literal><jee:local-slsb/></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><jee:local-slsb/></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><jee:remote-slsb/></literal></title>
|
||||
<para>The <literal><jee:remote-slsb/></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><property-placeholder/></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><annotation-config/></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><component-scan/></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><load-time-weaver/></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><spring-configured/></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><mbean-export/></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>
|
||||
|
||||
Reference in New Issue
Block a user