From c37080d49d14a49bd6da2104946f5aaf20ab3969 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sun, 25 Nov 2012 18:04:46 -0800 Subject: [PATCH] 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 mark-up - Fix misplaced tags - Fix tags to - Cleanup trailing whitespace and tabs Issue: SPR-10032 --- src/reference/docbook/aop-api.xml | 188 ++- src/reference/docbook/aop.xml | 653 ++++----- .../docbook/beans-annotation-config.xml | 70 +- .../docbook/beans-classpath-scanning.xml | 44 +- .../docbook/beans-context-additional.xml | 50 +- src/reference/docbook/beans-customizing.xml | 29 +- src/reference/docbook/beans-dependencies.xml | 174 +-- .../docbook/beans-extension-points.xml | 50 +- src/reference/docbook/beans-java.xml | 66 +- src/reference/docbook/beans-scopes.xml | 58 +- .../docbook/beans-standard-annotations.xml | 94 +- src/reference/docbook/beans.xml | 114 +- src/reference/docbook/cache.xml | 888 ++++++------ src/reference/docbook/cci.xml | 60 +- src/reference/docbook/classic-aop-spring.xml | 654 +++++---- src/reference/docbook/classic-spring.xml | 56 +- src/reference/docbook/dao.xml | 26 +- src/reference/docbook/dtd.xml | 616 ++++----- src/reference/docbook/dynamic-languages.xml | 130 +- src/reference/docbook/ejb.xml | 378 +++--- src/reference/docbook/expressions.xml | 355 ++--- src/reference/docbook/index.xml | 245 ++-- src/reference/docbook/jdbc.xml | 307 ++--- src/reference/docbook/jms.xml | 70 +- src/reference/docbook/jmx.xml | 166 +-- src/reference/docbook/mail.xml | 330 ++--- src/reference/docbook/mvc.xml | 1194 +++++++++-------- src/reference/docbook/new-in-3.0.xml | 102 +- src/reference/docbook/new-in-3.1.xml | 104 +- src/reference/docbook/new-in-3.2.xml | 62 +- src/reference/docbook/orm.xml | 218 +-- src/reference/docbook/overview.xml | 244 ++-- src/reference/docbook/oxm.xml | 281 ++-- src/reference/docbook/portlet.xml | 108 +- src/reference/docbook/preface.xml | 12 +- src/reference/docbook/remoting.xml | 238 ++-- src/reference/docbook/resources.xml | 90 +- src/reference/docbook/scheduling.xml | 104 +- src/reference/docbook/spring-form.tld.xml | 172 +-- src/reference/docbook/spring.tld.xml | 334 ++--- src/reference/docbook/swf-sidebar.xml | 13 +- src/reference/docbook/testing.xml | 58 +- .../docbook/titlepage/spring-html.xml | 65 + .../docbook/titlepage/spring-pdf.xml | 101 ++ src/reference/docbook/transaction.xml | 327 ++--- src/reference/docbook/validation.xml | 204 +-- src/reference/docbook/view.xml | 336 ++--- src/reference/docbook/web-integration.xml | 336 ++--- src/reference/docbook/xml-custom.xml | 430 +++--- src/reference/docbook/xsd-configuration.xml | 144 +- 50 files changed, 5765 insertions(+), 5383 deletions(-) create mode 100644 src/reference/docbook/titlepage/spring-html.xml create mode 100644 src/reference/docbook/titlepage/spring-pdf.xml diff --git a/src/reference/docbook/aop-api.xml b/src/reference/docbook/aop-api.xml index eb60c6c2cb..4099fbc940 100644 --- a/src/reference/docbook/aop-api.xml +++ b/src/reference/docbook/aop-api.xml @@ -1,11 +1,15 @@ - + 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"> Spring AOP APIs -
+
Introduction 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.
-
+
Pointcut API in Spring Let's look at how Spring handles the crucial pointcut concept. -
+
Concepts Spring's pointcut model enables pointcut reuse independent of @@ -93,7 +97,7 @@
-
+
Operations on pointcuts Spring supports operations on pointcuts: notably, @@ -123,7 +127,7 @@
-
+
AspectJ expression pointcuts Since 2.0, the most important type of pointcut used by Spring is @@ -135,14 +139,14 @@ pointcut primitives.
-
+
Convenience pointcut implementations Spring provides several convenient pointcut implementations. Some can be used out of the box; others are intended to be subclassed in application-specific pointcuts. -
+
Static pointcuts Static pointcuts are based on method and target class, and @@ -155,7 +159,7 @@ Let's consider some static pointcut implementations included with Spring. -
+
Regular expression pointcuts One obvious way to specify static pointcuts is regular @@ -172,7 +176,7 @@ The usage is shown below: - <bean id="settersAndAbsquatulatePointcut" + <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: - <bean id="settersAndAbsquatulateAdvisor" + <bean id="settersAndAbsquatulateAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="beanNameOfAopAllianceInterceptor"/> @@ -208,7 +212,7 @@ with any Advice type.
-
+
Attribute-driven pointcuts An important type of static pointcut is a @@ -217,7 +221,7 @@
-
+
Dynamic pointcuts Dynamic pointcuts are costlier to evaluate than static @@ -229,7 +233,7 @@ The main example is the control flow pointcut. -
+
Control flow pointcuts Spring control flow pointcuts are conceptually similar to @@ -252,7 +256,7 @@
-
+
Pointcut superclasses Spring provides useful pointcut superclasses to help you to @@ -274,7 +278,7 @@ RC2 and above.
-
+
Custom pointcuts Because pointcuts in Spring AOP are Java classes, rather than @@ -291,12 +295,12 @@
-
+
Advice API in Spring Let's now look at how Spring AOP handles advice. -
+
Advice lifecycles Each advice is a Spring bean. An advice instance can be shared @@ -317,14 +321,14 @@ the same AOP proxy.
-
+
Advice types in Spring 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. -
+
Interception around advice The most fundamental advice type in Spring is @@ -335,7 +339,7 @@ around advice should implement the following interface: public interface MethodInterceptor extends Interceptor { - + Object invoke(MethodInvocation invocation) throws Throwable; } @@ -379,7 +383,7 @@
-
+
Before advice A simpler advice type is a before @@ -422,8 +426,8 @@ ++count; } - public int getCount() { - return count; + public int getCount() { + return count; } } @@ -432,7 +436,7 @@
-
+
Throws advice Throws advice 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 @@
-
+
After Returning advice An after returning advice in Spring must implement the @@ -515,7 +519,7 @@ 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; } @@ -549,30 +553,30 @@
-
- +
+ Introduction advice - + Spring treats introduction advice as a special kind of interception advice. - + Introduction requires an IntroductionAdvisor, and an IntroductionInterceptor, implementing the following interface: - + public interface IntroductionInterceptor extends MethodInterceptor { boolean implementsInterface(Class intf); } - + The invoke() method inherited from the AOP Alliance MethodInterceptor interface must implement @@ -581,53 +585,47 @@ the method call - it cannot invoke proceed(). - + 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 IntroductionAdvisor, which has the following methods: - + 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(); } - + There is no MethodMatcher, and hence no Pointcut, associated with introduction advice. Only class filtering is logical. - + The getInterfaces() method returns the interfaces introduced by this advisor. - The - - validateInterfaces() - - method is used internally to see whether or not the introduced interfaces can be implemented by the configured - - IntroductionInterceptor - - . + The validateInterfaces() method is used internally to + see whether or not the introduced interfaces can be implemented by the configured + IntroductionInterceptor. 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: - + public interface Lockable { @@ -637,7 +635,7 @@ public interface IntroductionInfo { } - + This illustrates a mixin. 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. - + Firstly, we'll need an IntroductionInterceptor that does the heavy @@ -658,7 +656,7 @@ public interface IntroductionInfo { DelegatingIntroductionInterceptor is best for most cases. - + The DelegatingIntroductionInterceptor 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. - + Thus LockMixin subclasses DelegatingIntroductionInterceptor 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. - + Note the use of the locked instance variable. This effectively adds additional state to that held in the target object. - + - public class LockMixin extends DelegatingIntroductionInterceptor + public class LockMixin extends DelegatingIntroductionInterceptor implements Lockable { private boolean locked; @@ -725,7 +723,7 @@ public interface IntroductionInfo { } - + Often it isn't necessary to override the invoke() 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. - + The introduction advisor required is simple. All it needs to do is hold a distinct LockMixin instance, and specify @@ -746,7 +744,7 @@ public interface IntroductionInfo { LockMixin, so we simply create it using new. - + public class LockMixinAdvisor extends DefaultIntroductionAdvisor { @@ -757,7 +755,7 @@ public interface IntroductionInfo { } - + We can apply this advisor very simply: it requires no configuration. (However, it is necessary: It's @@ -768,7 +766,7 @@ public interface IntroductionInfo { hence LockMixin, for each advised object. The advisor comprises part of the advised object's state. - + We can apply this advisor programmatically, using the Advised.addAdvisor() method, or (the recommended @@ -776,12 +774,12 @@ public interface IntroductionInfo { choices discussed below, including "auto proxy creators," correctly handle introductions and stateful mixins. - +
-
+
Advisor API in Spring 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.
-
+
Using the ProxyFactoryBean to create AOP proxies 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. -
+
Basics The ProxyFactoryBean, like other Spring @@ -843,7 +841,7 @@ public interface IntroductionInfo { pluggability provided by Dependency Injection.
-
+
JavaBean properties In common with most FactoryBean @@ -949,7 +947,7 @@ public interface IntroductionInfo {
-
+
JDK- and CGLIB-based proxies 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.
-
+
Proxying interfaces 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.
-
+
Proxying classes 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.
-
+
Using 'global' advisors By appending an asterisk to an interceptor name, all advisors with @@ -1212,7 +1210,7 @@ public interface IntroductionInfo {
-
+
Concise proxy definitions Especially when defining transactional proxies, you may end up with @@ -1275,7 +1273,7 @@ public interface IntroductionInfo { it.
-
+
Creating AOP proxies programmatically with the ProxyFactory It's easy to create AOP proxies programmatically using Spring. This @@ -1312,7 +1310,7 @@ MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();
-
+
Manipulating advised objects However you create AOP proxies, you can manipulate them using the @@ -1324,7 +1322,7 @@ MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();
-
+
Using the "autoproxy" facility So far we've considered explicit creation of AOP proxies using a @@ -1437,13 +1435,13 @@ assertEquals("Added two advisors", -
+
Autoproxy bean definitions The org.springframework.aop.framework.autoproxy package provides the following standard autoproxy creators. -
+
BeanNameAutoProxyCreator The BeanNameAutoProxyCreator class is a @@ -1480,7 +1478,7 @@ assertEquals("Added two advisors", differently to different beans.
-
+
DefaultAdvisorAutoProxyCreator 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.
-
+
AbstractAdvisorAutoProxyCreator This is the superclass of DefaultAdvisorAutoProxyCreator. You @@ -1570,7 +1568,7 @@ assertEquals("Added two advisors",
-
+
Using metadata-driven auto-proxying 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): - <bean id="transactionManager" + <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/> @@ -1718,7 +1716,7 @@ assertEquals("Added two advisors",
-
+
Using TargetSources Spring offers the concept of a TargetSource, @@ -1747,7 +1745,7 @@ assertEquals("Added two advisors", Spring to create a new target instance when required. -
+
Hot swappable target sources The @@ -1761,7 +1759,7 @@ assertEquals("Added two advisors", You can change the target via the swap() method on HotSwappableTargetSource as follows: - HotSwappableTargetSource swapper = + HotSwappableTargetSource swapper = (HotSwappableTargetSource) beanFactory.getBean("swapper"); Object oldTarget = swapper.swap(newTarget); @@ -1788,7 +1786,7 @@ Object oldTarget = swapper.swap(newTarget); with arbitrary advice.
-
+
Pooling target sources Using a pooling target source provides a similar programming model @@ -1809,7 +1807,7 @@ Object oldTarget = swapper.swap(newTarget); Sample configuration is shown below: - <bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject" + <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()); set the TargetSources used by any autoproxy creator.
-
+
Prototype target sources Setting up a "prototype" target source is similar to a pooling @@ -1896,7 +1894,7 @@ System.out.println("Max pool size is " + conf.getMaxSize()); must be a prototype bean definition.
-
+
<classname>ThreadLocal</classname> target sources ThreadLocal target sources are useful if @@ -1928,7 +1926,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());
-
+
Defining new <interfacename>Advice</interfacename> types Spring AOP is designed to be extensible. While the interception @@ -1949,7 +1947,7 @@ System.out.println("Max pool size is " + conf.getMaxSize()); Javadocs for further information.
-
+
Further resources Please refer to the Spring sample applications for further examples diff --git a/src/reference/docbook/aop.xml b/src/reference/docbook/aop.xml index a555d91f7b..c85432caab 100644 --- a/src/reference/docbook/aop.xml +++ b/src/reference/docbook/aop.xml @@ -1,11 +1,15 @@ - + 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"> Aspect Oriented Programming with Spring -
+
Introduction Aspect-Oriented Programming (AOP) complements @@ -57,12 +61,12 @@ - If you are interested only in generic declarative services + If you are interested only in generic declarative services or other pre-packaged declarative middleware services such as pooling, you do not need to work directly with Spring AOP, and can skip most of this - chapter. + chapter. -
+
AOP concepts Let us begin by defining some central AOP concepts and @@ -206,7 +210,7 @@ service layer).
-
+
Spring AOP capabilities and goals Spring AOP is implemented in pure Java. There is no need for a @@ -276,7 +280,7 @@
-
+
AOP Proxies Spring AOP defaults to using standard J2SE dynamic @@ -300,23 +304,23 @@
-
+
@AspectJ support @AspectJ refers to a style of declaring aspects as regular Java classes annotated with Java 5 annotations. The @AspectJ style was - introduced by the AspectJ - project as part of the AspectJ 5 release. Spring 2.0 interprets + introduced by the AspectJ + project as part of the AspectJ 5 release. Spring 2.0 interprets the same annotations as AspectJ 5, using a library supplied by AspectJ for pointcut parsing and matching. The AOP runtime is still pure Spring AOP though, and there is no dependency on the AspectJ compiler or weaver. - Using the AspectJ compiler and weaver enables use of the + Using the AspectJ compiler and weaver enables use of the full AspectJ language, and is discussed in . + linkend="aop-using-aspectj" />. -
+
Enabling @AspectJ Support To use @AspectJ aspects in a Spring configuration you need to @@ -334,7 +338,7 @@ This library is available in the 'lib' directory of an AspectJ distribution or via the Maven Central repository. -
+
Enabling @AspectJ Support with Java configuration To enable @AspectJ support with Java @@ -348,7 +352,7 @@ public class AppConfig { }
-
+
Enabling @AspectJ Support with XML configuration To enable @AspectJ support with XML based configuration use the @@ -369,7 +373,7 @@ public class AppConfig {
-
+
Declaring an aspect With the @AspectJ support enabled, any bean defined in your @@ -429,7 +433,7 @@ public class NotVeryUsefulAspect {
-
+
Declaring a pointcut Recall that pointcuts determine join points of interest, and thus @@ -457,15 +461,15 @@ private void anyOldTransfer() {}// the pointcut signatureThe pointcut expression that forms the value of the @Pointcut annotation is a regular AspectJ 5 pointcut expression. For a full discussion of AspectJ's pointcut - language, see the AspectJ - Programming Guide (and for Java 5 based extensions, the AspectJ - 5 Developers Notebook) or one of the books on AspectJ such as + language, see the AspectJ + Programming Guide (and for Java 5 based extensions, the AspectJ + 5 Developers Notebook) or one of the books on AspectJ such as Eclipse AspectJ by Colyer et. al. or AspectJ in Action by Ramnivas Laddad. -
+
Supported Pointcut Designators Spring AOP supports the following AspectJ pointcut designators @@ -611,7 +615,7 @@ private void anyOldTransfer() {}// the pointcut signature
-
+
Combining pointcut expressions Pointcut expressions can be combined using '&&', '||' @@ -626,10 +630,10 @@ private void anyOldTransfer() {}// the pointcut signature @Pointcut("execution(public * *(..))") private void anyPublicOperation() {} - + @Pointcut("within(com.xyz.someapp.trading..*)") private void inTrading() {} - + @Pointcut("anyPublicOperation() && inTrading()") private void tradingOperation() {} @@ -641,7 +645,7 @@ private void anyOldTransfer() {}// the pointcut signaturematching.
-
+
Sharing common pointcut definitions When working with enterprise applications, you often want to @@ -668,7 +672,7 @@ public class SystemArchitecture { /** * A join point is in the service layer if the method is defined - * in a type in the com.xyz.someapp.service package or any sub-package + * in a type in the com.xyz.someapp.service package or any sub-package * under that. */ @Pointcut("within(com.xyz.someapp.service..*)") @@ -676,7 +680,7 @@ public class SystemArchitecture { /** * A join point is in the data access layer if the method is defined - * in a type in the com.xyz.someapp.dao package or any sub-package + * in a type in the com.xyz.someapp.dao package or any sub-package * under that. */ @Pointcut("within(com.xyz.someapp.dao..*)") @@ -686,23 +690,23 @@ public class SystemArchitecture { * A business service is the execution of any method defined on a service * interface. This definition assumes that interfaces are placed in the * "service" package, and that implementation types are in sub-packages. - * - * If you group service interfaces by functional area (for example, - * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then - * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" + * + * If you group service interfaces by functional area (for example, + * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then + * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" * could be used instead. * - * Alternatively, you can write the expression using the 'bean' - * PCD, like so "bean(*Service)". (This assumes that you have + * Alternatively, you can write the expression using the 'bean' + * PCD, like so "bean(*Service)". (This assumes that you have * named your Spring service beans in a consistent fashion.) */ @Pointcut("execution(* com.xyz.someapp.service.*.*(..))") public void businessService() {} - + /** - * A data access operation is the execution of any method defined on a + * A data access operation is the execution of any method defined on a * dao interface. This definition assumes that interfaces are placed in the - * "dao" package, and that implementation types are in sub-packages. + * "dao" package, and that implementation types are in sub-packages. */ @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))") public void dataAccessOperation() {} @@ -714,7 +718,7 @@ public class SystemArchitecture { service layer transactional, you could write: <aop:config> - <aop:advisor + <aop:advisor pointcut="com.xyz.someapp.SystemArchitecture.businessService()" advice-ref="tx-advice"/> </aop:config> @@ -731,7 +735,7 @@ public class SystemArchitecture { .
-
+
Examples Spring AOP users are likely to use the @@ -756,9 +760,9 @@ public class SystemArchitecture { (*) matches a method taking one parameter of any type, (*,String) matches a method taking two parameters, the first can be of any type, the second must be a String. - Consult the - Language Semantics section of the AspectJ Programming Guide + Consult the + Language Semantics section of the AspectJ Programming Guide for more information. Some examples of common pointcut expressions are given @@ -820,9 +824,9 @@ public class SystemArchitecture { this(com.xyz.service.AccountService) - 'this' is more commonly used in a binding form :- + 'this' is more commonly used in a binding form :- see the following section on advice for how to make the proxy - object available in the advice body. + object available in the advice body. @@ -832,9 +836,9 @@ public class SystemArchitecture { target(com.xyz.service.AccountService) - 'target' is more commonly used in a binding form :- + 'target' is more commonly used in a binding form :- see the following section on advice for how to make the target - object available in the advice body. + object available in the advice body. @@ -863,9 +867,9 @@ public class SystemArchitecture { @target(org.springframework.transaction.annotation.Transactional) - '@target' can also be used in a binding form :- see + '@target' can also be used in a binding form :- see the following section on advice for how to make the annotation - object available in the advice body. + object available in the advice body. @@ -875,9 +879,9 @@ public class SystemArchitecture { @within(org.springframework.transaction.annotation.Transactional) - '@within' can also be used in a binding form :- see + '@within' can also be used in a binding form :- see the following section on advice for how to make the annotation - object available in the advice body. + object available in the advice body. @@ -887,9 +891,9 @@ public class SystemArchitecture { @annotation(org.springframework.transaction.annotation.Transactional) - '@annotation' can also be used in a binding form :- + '@annotation' can also be used in a binding form :- see the following section on advice for how to make the annotation - object available in the advice body. + object available in the advice body. @@ -900,9 +904,9 @@ public class SystemArchitecture { @args(com.xyz.security.Classified) - '@args' can also be used in a binding form :- see + '@args' can also be used in a binding form :- see the following section on advice for how to make the annotation - object(s) available in the advice body. + object(s) available in the advice body. @@ -921,38 +925,38 @@ public class SystemArchitecture {
-
+
Writing good pointcuts - During compilation, AspectJ processes pointcuts in order to try and optimize matching performance. Examining code - and determining if each join point matches (statically or dynamically) a given pointcut is a costly process. (A dynamic - match means the match cannot be fully determined from static analysis and a test will be placed in the code to - determine if there is an actual match when the code is running). On first encountering a pointcut declaration, - AspectJ will rewrite it into an optimal form for the matching process. What does this mean? Basically pointcuts - are rewritten in DNF (Disjunctive Normal Form) and the components of the pointcut are sorted such that those - components that are cheaper to evaluate are checked first. This means you do not have to worry about understanding + During compilation, AspectJ processes pointcuts in order to try and optimize matching performance. Examining code + and determining if each join point matches (statically or dynamically) a given pointcut is a costly process. (A dynamic + match means the match cannot be fully determined from static analysis and a test will be placed in the code to + determine if there is an actual match when the code is running). On first encountering a pointcut declaration, + AspectJ will rewrite it into an optimal form for the matching process. What does this mean? Basically pointcuts + are rewritten in DNF (Disjunctive Normal Form) and the components of the pointcut are sorted such that those + components that are cheaper to evaluate are checked first. This means you do not have to worry about understanding the performance of various pointcut designators and may supply them in any order in a pointcut declaration. - - However, AspectJ can only work with what it is told, and for optimal performance of matching you should - think about what they are trying to achieve and narrow the search space for matches as much as possible in the + + However, AspectJ can only work with what it is told, and for optimal performance of matching you should + think about what they are trying to achieve and narrow the search space for matches as much as possible in the definition. The existing designators naturally fall into one of three groups: kinded, scoping and context: - Kinded designators are those which select a particular kind of join point. For example: execution, get, set, call, handler - Scoping designators are those which select a group of join points of interest (of probably many kinds). For example: within, withincode - Contextual designators are those that match (and optionally bind) based on context. For example: this, target, @annotation + Kinded designators are those which select a particular kind of join point. For example: execution, get, set, call, handler + Scoping designators are those which select a group of join points of interest (of probably many kinds). For example: within, withincode + Contextual designators are those that match (and optionally bind) based on context. For example: this, target, @annotation - - A well written pointcut should try and include at least the first two types (kinded and scoping), whilst - the contextual designators may be included if wishing to match based on join point context, or bind that context - for use in the advice. Supplying either just a kinded designator or just a contextual designator will work but - could affect weaving performance (time and memory used) due to all the extra processing and analysis. Scoping - designators are very fast to match and their usage means AspectJ can very quickly dismiss groups of - join points that should not be further processed - that is why a good pointcut should always include - one if possible. + + A well written pointcut should try and include at least the first two types (kinded and scoping), whilst + the contextual designators may be included if wishing to match based on join point context, or bind that context + for use in the advice. Supplying either just a kinded designator or just a contextual designator will work but + could affect weaving performance (time and memory used) due to all the extra processing and analysis. Scoping + designators are very fast to match and their usage means AspectJ can very quickly dismiss groups of + join points that should not be further processed - that is why a good pointcut should always include + one if possible.
-
+
Declaring advice Advice is associated with a pointcut expression, and runs before, @@ -960,7 +964,7 @@ public class SystemArchitecture { expression may be either a simple reference to a named pointcut, or a pointcut expression declared in place. -
+
Before advice Before advice is declared in an aspect using the @@ -996,7 +1000,7 @@ public class BeforeExample { }
-
+
After returning advice After returning advice runs when a matched method execution @@ -1038,7 +1042,7 @@ public class AfterReturningExample { public void doAccessCheck(Object retVal) { // ... } - + } The name used in the returning attribute must @@ -1055,7 +1059,7 @@ public class AfterReturningExample { advice.
-
+
After throwing advice After throwing advice runs when a matched method execution exits @@ -1107,7 +1111,7 @@ public class AfterThrowingExample { (DataAccessException in this case).
-
+
After (finally) advice After (finally) advice runs however a matched method execution @@ -1130,7 +1134,7 @@ public class AfterFinallyExample { }
-
+
Around advice The final kind of advice is around advice. Around advice runs @@ -1155,7 +1159,7 @@ public class AfterFinallyExample { execution when it proceeds. The behavior of proceed when called with an - Object[] is a little different than the + Object[] is a little different than the behavior of proceed for around advice compiled by the AspectJ compiler. For around advice written using the traditional AspectJ language, the number of arguments passed to proceed must match the @@ -1197,7 +1201,7 @@ public class AroundExample { quite legal.
-
+
Advice parameters Spring 2.0 offers fully typed advice - meaning that you declare @@ -1209,7 +1213,7 @@ public class AroundExample { that can find out about the method the advice is currently advising. -
+
Access to the current <interfacename>JoinPoint</interfacename> @@ -1231,7 +1235,7 @@ public class AroundExample { details.
-
+
Passing parameters to advice We've already seen how to bind the returned value or exception @@ -1245,7 +1249,7 @@ public class AroundExample { Account object as the first parameter, and you need access to the account in the advice body. You could write the following: - @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" + + @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" + "args(account,..)") public void validateAccount(Account account) { // ... @@ -1264,7 +1268,7 @@ public void validateAccount(Account account) { matches a join point, and then just refer to the named pointcut from the advice. This would look as follows: - @Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" + + @Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" + "args(account,..)") private void accountDataAccessOperation(Account account) {} @@ -1290,13 +1294,13 @@ public void validateAccount(Account account) { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Auditable { - AuditCode value(); + AuditCode value(); } And then the advice that matches the execution of @Auditable methods: - @Before("com.xyz.lib.Pointcuts.anyPublicMethod() && " + + @Before("com.xyz.lib.Pointcuts.anyPublicMethod() && " + "@annotation(auditable)") public void audit(Auditable auditable) { AuditCode code = auditable.value(); @@ -1304,7 +1308,7 @@ public void audit(Auditable auditable) { }
-
+
Advice parameters and generics Spring AOP can handle generics used in class declarations and @@ -1342,7 +1346,7 @@ public void beforeSampleMethod(Collection<MyType> param) { check the type of the elements.
-
+
Determining argument names The parameter binding in advice invocations relies on matching @@ -1421,7 +1425,7 @@ public void audit(JoinPoint jp) { If an @AspectJ aspect has been compiled by the AspectJ compiler (ajc) even without the debug information then there is - no need to add the argNames attribute as the + no need to add the argNames attribute as the compiler will retain the needed information. @@ -1445,7 +1449,7 @@ public void audit(JoinPoint jp) {
-
+
Proceeding with arguments We remarked earlier that we would describe how to write a @@ -1456,12 +1460,12 @@ public void audit(JoinPoint jp) { @Around("execution(List<Account> find*(..)) &&" + "com.xyz.myapp.SystemArchitecture.inDataAccessLayer() && " + - "args(accountHolderNamePattern)") + "args(accountHolderNamePattern)") public Object preProcessQueryPattern(ProceedingJoinPoint pjp, String accountHolderNamePattern) throws Throwable { String newPattern = preProcess(accountHolderNamePattern); return pjp.proceed(new Object[] {newPattern}); -} +} In many cases you will be doing this binding anyway (as in the @@ -1469,7 +1473,7 @@ throws Throwable {
-
+
Advice ordering What happens when multiple pieces of advice all want to run at @@ -1504,7 +1508,7 @@ throws Throwable {
-
+
Introductions Introductions (known as inter-type declarations in AspectJ) enable @@ -1528,13 +1532,13 @@ public class UsageTracking { @DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class) public static UsageTracked mixin; - + @Before("com.xyz.myapp.SystemArchitecture.businessService() &&" + "this(usageTracked)") public void recordUsage(UsageTracked usageTracked) { usageTracked.incrementUseCount(); } - + } The interface to be implemented is determined by the type of the @@ -1549,7 +1553,7 @@ public class UsageTracking { UsageTracked usageTracked = (UsageTracked) context.getBean("myService");
-
+
Aspect instantiation models (This is an advanced topic, so if you are just starting out with @@ -1572,12 +1576,12 @@ public class UsageTracking { public class MyAspect { private int someState; - + @Before(com.xyz.myapp.SystemArchitecture.businessService()) public void recordServiceUsage() { // ... } - + } The effect of the 'perthis' clause is that one @@ -1597,7 +1601,7 @@ public class MyAspect { each unique target object at matched join points.
-
+
Example Now that you have seen how all the constituent parts work, let's @@ -1620,7 +1624,7 @@ public class MyAspect { @Aspect public class ConcurrentOperationExecutor implements Ordered { - + private static final int DEFAULT_MAX_RETRIES = 2; private int maxRetries = DEFAULT_MAX_RETRIES; @@ -1629,22 +1633,22 @@ public class ConcurrentOperationExecutor implements Ordered { public void setMaxRetries(int maxRetries) { this.maxRetries = maxRetries; } - + public int getOrder() { return this.order; } - + public void setOrder(int order) { this.order = order; } - + @Around("com.xyz.myapp.SystemArchitecture.businessService()") - public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { + public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { int numAttempts = 0; PessimisticLockingFailureException lockFailureException; do { numAttempts++; - try { + try { return pjp.proceed(); } catch(PessimisticLockingFailureException ex) { @@ -1677,7 +1681,7 @@ public class ConcurrentOperationExecutor implements Ordered { <bean id="concurrentOperationExecutor" class="com.xyz.myapp.service.impl.ConcurrentOperationExecutor"> <property name="maxRetries" value="3"/> - <property name="order" value="100"/> + <property name="order" value="100"/> </bean> To refine the aspect so that it only retries idempotent @@ -1694,15 +1698,15 @@ public @interface Idempotent { simply involves refining the pointcut expression so that only @Idempotent operations match: - @Around("com.xyz.myapp.SystemArchitecture.businessService() && " + + @Around("com.xyz.myapp.SystemArchitecture.businessService() && " + "@annotation(com.xyz.myapp.service.Idempotent)") -public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { - ... +public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { + ... }
-
+
Schema-based AOP support If you are unable to use Java 5, or simply prefer an XML-based @@ -1740,7 +1744,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { AutoProxyCreator style. -
+
Declaring an aspect Using the schema support, an aspect is simply a regular Java @@ -1767,7 +1771,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { other Spring bean.
-
+
Declaring a pointcut A named pointcut can be declared inside an <aop:config> @@ -1779,7 +1783,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:config> - <aop:pointcut id="businessService" + <aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..))"/> </aop:config> @@ -1795,7 +1799,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:config> - <aop:pointcut id="businessService" + <aop:pointcut id="businessService" expression="com.xyz.myapp.SystemArchitecture.businessService()"/> </aop:config> @@ -1810,11 +1814,11 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="myAspect" ref="aBean"> - <aop:pointcut id="businessService" + <aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..))"/> - + ... - + </aop:aspect> </aop:config> @@ -1828,11 +1832,11 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="myAspect" ref="aBean"> - <aop:pointcut id="businessService" + <aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..)) &amp;&amp; this(service)"/> <aop:before pointcut-ref="businessService" method="monitor"/> ... - + </aop:aspect> </aop:config> @@ -1853,12 +1857,12 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="myAspect" ref="aBean"> - <aop:pointcut id="businessService" + <aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..)) and this(service)"/> <aop:before pointcut-ref="businessService" method="monitor"/> ... - + </aop:aspect> </aop:config> @@ -1870,13 +1874,13 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { style.
-
+
Declaring advice The same five advice kinds are supported as for the @AspectJ style, and they have exactly the same semantics. -
+
Before advice Before advice runs before a matched method execution. It is @@ -1885,12 +1889,12 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="beforeExample" ref="aBean"> - <aop:before - pointcut-ref="dataAccessOperation" + <aop:before + pointcut-ref="dataAccessOperation" method="doAccessCheck"/> - + ... - + </aop:aspect> Here dataAccessOperation is the id of a @@ -1901,12 +1905,12 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="beforeExample" ref="aBean"> - <aop:before - pointcut="execution(* com.xyz.myapp.dao.*.*(..))" + <aop:before + pointcut="execution(* com.xyz.myapp.dao.*.*(..))" method="doAccessCheck"/> - + ... - + </aop:aspect> As we noted in the discussion of the @AspectJ style, using named @@ -1922,7 +1926,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { invoked.
-
+
After returning advice After returning advice runs when a matched method execution @@ -1932,12 +1936,12 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="afterReturningExample" ref="aBean"> - <aop:after-returning - pointcut-ref="dataAccessOperation" + <aop:after-returning + pointcut-ref="dataAccessOperation" method="doAccessCheck"/> - + ... - + </aop:aspect> Just as in the @AspectJ style, it is possible to get hold of the @@ -1947,13 +1951,13 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="afterReturningExample" ref="aBean"> - <aop:after-returning + <aop:after-returning pointcut-ref="dataAccessOperation" - returning="retVal" + returning="retVal" method="doAccessCheck"/> - + ... - + </aop:aspect> The doAccessCheck method must declare a parameter named @@ -1964,7 +1968,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { public void doAccessCheck(Object retVal) {...
-
+
After throwing advice After throwing advice executes when a matched method execution @@ -1975,11 +1979,11 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="afterThrowingExample" ref="aBean"> <aop:after-throwing - pointcut-ref="dataAccessOperation" + pointcut-ref="dataAccessOperation" method="doRecoveryActions"/> - + ... - + </aop:aspect> Just as in the @AspectJ style, it is possible to get hold of the @@ -1989,13 +1993,13 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="afterThrowingExample" ref="aBean"> - <aop:after-throwing + <aop:after-throwing pointcut-ref="dataAccessOperation" - throwing="dataAccessEx" + throwing="dataAccessEx" method="doRecoveryActions"/> - + ... - + </aop:aspect> The doRecoveryActions method must declare a parameter named @@ -2006,7 +2010,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { public void doRecoveryActions(DataAccessException dataAccessEx) {...
-
+
After (finally) advice After (finally) advice runs however a matched method execution @@ -2016,15 +2020,15 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="afterFinallyExample" ref="aBean"> <aop:after - pointcut-ref="dataAccessOperation" + pointcut-ref="dataAccessOperation" method="doReleaseLock"/> - + ... - + </aop:aspect>
-
+
Around advice The final kind of advice is around advice. Around advice runs @@ -2053,11 +2057,11 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { <aop:aspect id="aroundExample" ref="aBean"> <aop:around - pointcut-ref="businessService" + pointcut-ref="businessService" method="doBasicProfiling"/> - + ... - + </aop:aspect> The implementation of the doBasicProfiling @@ -2072,7 +2076,7 @@ public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { }
-
+
Advice parameters The schema based declaration style supports fully typed advice @@ -2195,7 +2199,7 @@ ms % Task name 00000 ? execution(getFoo)
-
+
Advice ordering When multiple advice needs to execute at the same join point @@ -2208,7 +2212,7 @@ ms % Task name
-
+
Introductions Introductions (known as inter-type declarations in AspectJ) enable @@ -2233,12 +2237,12 @@ ms % Task name types-matching="com.xzy.myapp.service.*+" implement-interface="com.xyz.myapp.service.tracking.UsageTracked" default-impl="com.xyz.myapp.service.tracking.DefaultUsageTracked"/> - + <aop:before pointcut="com.xyz.myapp.SystemArchitecture.businessService() and this(usageTracked)" method="recordUsage"/> - + </aop:aspect> The class backing the usageTracking bean would @@ -2261,7 +2265,7 @@ ms % Task name UsageTracked usageTracked = (UsageTracked) context.getBean("myService");
-
+
Aspect instantiation models The only supported instantiation model for schema-defined aspects @@ -2269,7 +2273,7 @@ ms % Task name future releases.
-
+
Advisors The concept of "advisors" is brought forward from the AOP support @@ -2290,10 +2294,10 @@ ms % Task name <aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..))"/> - <aop:advisor + <aop:advisor pointcut-ref="businessService" advice-ref="tx-advice"/> - + </aop:config> <tx:advice id="tx-advice"> @@ -2301,17 +2305,18 @@ ms % Task name <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> + + As well as the pointcut-ref attribute used in the + above example, you can also use the pointcut attribute + to define a pointcut expression inline. + + To define the precedence of an advisor so that the advice can + participate in ordering, use the order attribute to + define the Ordered value of the advisor. +
- As well as the pointcut-ref attribute used in the - above example, you can also use the pointcut attribute - to define a pointcut expression inline. - - To define the precedence of an advisor so that the advice can - participate in ordering, use the order attribute to - define the Ordered value of the advisor. - -
+
Example Let's see how the concurrent locking failure retry example from @@ -2335,7 +2340,7 @@ ms % Task name schema support): public class ConcurrentOperationExecutor implements Ordered { - + private static final int DEFAULT_MAX_RETRIES = 2; private int maxRetries = DEFAULT_MAX_RETRIES; @@ -2344,21 +2349,21 @@ ms % Task name public void setMaxRetries(int maxRetries) { this.maxRetries = maxRetries; } - + public int getOrder() { return this.order; } - + public void setOrder(int order) { this.order = order; } - - public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { + + public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { int numAttempts = 0; PessimisticLockingFailureException lockFailureException; do { numAttempts++; - try { + try { return pjp.proceed(); } catch(PessimisticLockingFailureException ex) { @@ -2393,11 +2398,11 @@ ms % Task name <aop:pointcut id="idempotentOperation" expression="execution(* com.xyz.myapp.service.*.*(..))"/> - + <aop:around pointcut-ref="idempotentOperation" method="doConcurrentOperation"/> - + </aop:aspect> </aop:config> @@ -2405,7 +2410,7 @@ ms % Task name <bean id="concurrentOperationExecutor" class="com.xyz.myapp.service.impl.ConcurrentOperationExecutor"> <property name="maxRetries" value="3"/> - <property name="order" value="100"/> + <property name="order" value="100"/> </bean> Notice that for the time being we assume that all business @@ -2430,7 +2435,7 @@ public @interface Idempotent {
-
+
Choosing which AOP declaration style to use Once you have decided that an aspect is the best approach for @@ -2440,7 +2445,7 @@ public @interface Idempotent { by a number of factors including application requirements, development tools, and team familiarity with AOP. -
+
Spring AOP or full AspectJ? Use the simplest thing that can work. Spring AOP is simpler than @@ -2457,9 +2462,9 @@ public @interface Idempotent { syntax (also known as the "code style") or the @AspectJ annotation style. Clearly, if you are not using Java 5+ then the choice has been made for you... use the code style. If aspects play a large role in your - design, and you are able to use the AspectJ Development Tools - (AJDT) plugin for Eclipse, then the AspectJ language syntax is + design, and you are able to use the AspectJ Development Tools + (AJDT) plugin for Eclipse, then the AspectJ language syntax is the preferred option: it is cleaner and simpler because the language was purposefully designed for writing aspects. If you are not using Eclipse, or have only a few aspects that do not play a major role in your @@ -2468,7 +2473,7 @@ public @interface Idempotent { aspect weaving phase to your build script.
-
+
@AspectJ or XML for Spring AOP? If you have chosen to use Spring AOP, then you have a choice of @@ -2533,7 +2538,7 @@ public @interface Idempotent {
-
+
Mixing aspect types It is perfectly possible to mix @AspectJ style aspects using the @@ -2544,7 +2549,7 @@ public @interface Idempotent { support mechanism and will co-exist without any difficulty.
-
+
Proxying mechanisms Spring AOP uses either JDK dynamic proxies or CGLIB to create the @@ -2589,7 +2594,7 @@ public @interface Idempotent { - To force the use of CGLIB proxies set + To force the use of CGLIB proxies set the value of the proxy-target-class attribute of the <aop:config> element to true: @@ -2622,7 +2627,7 @@ public @interface Idempotent { CGLIB proxies for all three of them. -
+
Understanding AOP proxies Spring AOP is proxy-based. It is vitally @@ -2637,11 +2642,11 @@ public @interface Idempotent { public class SimplePojo implements Pojo { public void foo() { - // this next method invocation is a direct call on the 'this' reference + // this next method invocation is a direct + call on the 'this' reference this.bar(); } - + public void bar() { // some logic... } @@ -2668,10 +2673,10 @@ public @interface Idempotent { public class Main { public static void main(String[] args) { - + Pojo pojo = new SimplePojo(); - - // this is a direct method call on the 'pojo' reference + + // this is a direct method call on the 'pojo' reference pojo.foo(); } } @@ -2694,14 +2699,14 @@ public @interface Idempotent { public class Main { public static void main(String[] args) { - + ProxyFactory factory = new ProxyFactory(new SimplePojo()); factory.addInterface(Pojo.class); factory.addAdvice(new RetryAdvice()); Pojo pojo = (Pojo) factory.getProxy(); - - // this is a method call on the proxy! + + // this is a method call on the proxy! pojo.foo(); } } @@ -2737,7 +2742,7 @@ public @interface Idempotent { // this works, but... gah! ((Pojo) AopContext.currentProxy()).bar(); } - + public void bar() { // some logic... } @@ -2752,15 +2757,15 @@ public @interface Idempotent { public class Main { public static void main(String[] args) { - + ProxyFactory factory = new ProxyFactory(new SimplePojo()); factory.adddInterface(Pojo.class); factory.addAdvice(new RetryAdvice()); - factory.setExposeProxy(true); + factory.setExposeProxy(true); Pojo pojo = (Pojo) factory.getProxy(); - // this is a method call on the proxy! + // this is a method call on the proxy! pojo.foo(); } } @@ -2771,7 +2776,7 @@ public @interface Idempotent {
-
+
Programmatic creation of @AspectJ Proxies In addition to declaring aspects in your configuration using either @@ -2789,20 +2794,20 @@ public @interface Idempotent { illustrated below. See the Javadocs for full information. // create a factory that can generate a proxy for the given target object -AspectJProxyFactory factory = new AspectJProxyFactory(targetObject); +AspectJProxyFactory factory = new AspectJProxyFactory(targetObject); // add an aspect, the class must be an @AspectJ aspect // you can call this as many times as you need with different aspects factory.addAspect(SecurityManager.class); // you can also add existing aspect instances, the type of the object supplied must be an @AspectJ aspect -factory.addAspect(usageTracker); +factory.addAspect(usageTracker); // now get the proxy object... MyInterfaceType proxy = factory.getProxy();
-
+
Using AspectJ with Spring applications Everything we've covered so far in this chapter is pure Spring AOP. @@ -2821,7 +2826,7 @@ MyInterfaceType proxy = factory.getProxy(); linkend="aop-aj-ltw"/> provides an introduction to load-time weaving for Spring applications using AspectJ. -
+
Using AspectJ to dependency inject domain objects with Spring @@ -2887,10 +2892,10 @@ public class Account { @Configurable(autowire=Autowire.BY_TYPE) or @Configurable(autowire=Autowire.BY_NAME for autowiring by type or by name respectively. As an alternative, as of - Spring 2.5 it is preferable to specify explicit, annotation-driven - dependency injection for your @Configurable + Spring 2.5 it is preferable to specify explicit, annotation-driven + dependency injection for your @Configurable beans by using @Autowired or - @Inject at the field or method level (see + @Inject at the field or method level (see for further details). Finally you can enable Spring dependency checking for the object @@ -2912,8 +2917,8 @@ public class Account { to newly instantiated objects (e.g., objects instantiated with the 'new' operator) as well as to Serializable objects that are undergoing - deserialization (e.g., via readResolve()). + deserialization (e.g., via readResolve()). One of the key phrases in the above paragraph is 'in @@ -2933,18 +2938,18 @@ public class Account { @Configurable(preConstruction=true) You can find out more information about the language semantics - of the various pointcut types in AspectJ in - this appendix of the AspectJ - Programming Guide. + of the various pointcut types in AspectJ in + this appendix of the AspectJ + Programming Guide. For this to work the annotated types must be woven with the AspectJ weaver - you can either use a build-time Ant or Maven task to do - this (see for example the AspectJ - Development Environment Guide) or load-time weaving (see AspectJ + Development Environment Guide) or load-time weaving (see ). The AnnotationBeanConfigurerAspect itself needs configuring by Spring (in order to obtain a reference to the bean @@ -2969,7 +2974,7 @@ public class AppConfig { If you are using the DTD instead of schema, the equivalent definition is: - <bean + <bean class="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect" factory-method="aspectOf"/> @@ -3000,7 +3005,7 @@ public class AppConfig { through the container and once through the aspect. -
+
Unit testing <interfacename>@Configurable</interfacename> objects @@ -3020,7 +3025,7 @@ public class AppConfig { has not been configured by Spring.
-
+
Working with multiple application contexts The AnnotationBeanConfigurerAspect used @@ -3062,7 +3067,7 @@ public class AppConfig {
-
+
Other Spring aspects for AspectJ In addition to the @Configurable @@ -3115,13 +3120,13 @@ public class AppConfig { // the creation of a new bean (any object in the domain model) protected pointcut beanCreation(Object beanInstance) : initialization(new(..)) && - SystemArchitecture.inDomainModel() && + SystemArchitecture.inDomainModel() && this(beanInstance); - + }
-
+
Configuring AspectJ aspects using Spring IoC When using AspectJ aspects with Spring applications, it is natural @@ -3178,7 +3183,7 @@ public class AppConfig {
-
+
Load-time weaving with AspectJ in the Spring Framework Load-time weaving (LTW) refers to the process of weaving AspectJ @@ -3187,9 +3192,9 @@ public class AppConfig { configuring and using LTW in the specific context of the Spring Framework: this section is not an introduction to LTW though. For full details on the specifics of LTW and configuring LTW with just AspectJ - (with Spring not being involved at all), see the LTW - section of the AspectJ Development Environment Guide. + (with Spring not being involved at all), see the LTW + section of the AspectJ Development Environment Guide. The value-add that the Spring Framework brings to AspectJ LTW is in enabling much finer-grained control over the weaving process. @@ -3207,7 +3212,7 @@ public class AppConfig { without making any modifications to the application server's launch script that will be needed to add -javaagent:path/to/aspectjweaver.jar or (as we describe later in this - section) -javaagent:path/to/org.springframework.instrument-{version}.jar + section) -javaagent:path/to/org.springframework.instrument-{version}.jar (previously named spring-agent.jar). Developers simply modify one or more files that form the application context to enable load-time weaving instead of relying on administrators who typically are in charge @@ -3218,7 +3223,7 @@ public class AppConfig { specifics about elements introduced in the following example. For a complete example, please see the Petclinic sample application. -
+
A first example Let us assume that you are an application developer who has been @@ -3293,7 +3298,7 @@ public class ProfilingAspect { <aspects> - <!-- weave in just this aspect --> + <!-- weave in just this aspect --> <aspect name="foo.ProfilingAspect"/> </aspects> @@ -3315,9 +3320,9 @@ public class ProfilingAspect { xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 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/context +http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- a service object; we will be profiling its methods --> @@ -3363,13 +3368,13 @@ public final class Main { java -javaagent:C:/projects/foo/lib/global/spring-instrument.jar foo.Main The '-javaagent' is a Java 5+ flag for - specifying and enabling agents - to instrument programs running on the JVM. The Spring + specifying and enabling agents + to instrument programs running on the JVM. The Spring Framework ships with such an agent, the InstrumentationSavingAgent, which is packaged in the spring-instrument.jar - that + that was supplied as the value of the -javaagent argument in the above example. @@ -3432,7 +3437,7 @@ public final class Main {
-
+
Aspects The aspects that you use in LTW have to be AspectJ aspects. They @@ -3444,7 +3449,7 @@ public final class Main { available on the classpath.
-
+
'<filename>META-INF/aop.xml</filename>' The AspectJ LTW infrastructure is configured using one or more @@ -3452,9 +3457,9 @@ public final class Main { classpath (either directly, or more typically in jar files). The structure and contents of this file is detailed in the main - AspectJ reference documentation, and the interested reader is referred - to that resource. (I appreciate that this section is brief, + AspectJ reference documentation, and the interested reader is referred + to that resource. (I appreciate that this section is brief, but the 'aop.xml' file is 100% AspectJ - there is no Spring-specific information or semantics that apply to it, and so there is no extra value that I can contribute either as a result), so @@ -3462,7 +3467,7 @@ public final class Main { developers wrote, I am just directing you there.)
-
+
Required libraries (JARS) At a minimum you will need the following libraries to use the @@ -3492,7 +3497,7 @@ public final class Main {
-
+
Spring configuration The key component in Spring's LTW support is the @@ -3567,7 +3572,7 @@ http://www.springframework.org/schema/context 'automatically detected' is dependent upon your runtime environment (summarized in the following table). - +
<classname>DefaultContextLoadTimeWeaver</classname> <interfacename>LoadTimeWeavers</interfacename> @@ -3583,32 +3588,32 @@ http://www.springframework.org/schema/context - Running in BEA's - Weblogic 10 + Running in BEA's + Weblogic 10 WebLogicLoadTimeWeaver - Running in IBM WebSphere Application Server 7 + Running in IBM WebSphere Application Server 7 WebSphereLoadTimeWeaver - Running in Oracle's - OC4J + Running in Oracle's + OC4J OC4JLoadTimeWeaver - Running in GlassFish + Running in GlassFish GlassFishLoadTimeWeaver - Running in JBoss AS + Running in JBoss AS JBossLoadTimeWeaver @@ -3622,8 +3627,8 @@ http://www.springframework.org/schema/context Fallback, expecting the underlying ClassLoader to follow common conventions - (e.g. applicable to TomcatInstrumentableClassLoader and - Resin) + (e.g. applicable to TomcatInstrumentableClassLoader and + Resin) ReflectiveLoadTimeWeaver @@ -3693,7 +3698,7 @@ http://www.springframework.org/schema/context with the default value if the attribute is not present being 'autodetect' -
+
AspectJ weaving attribute values @@ -3735,22 +3740,22 @@ http://www.springframework.org/schema/context
-
+
Environment-specific configuration This last section contains any additional settings and configuration that you will need when using Spring's LTW support in environments such as application servers and web containers. -
+
Tomcat - Apache Tomcat's default class loader - does not support class transformation which is why Spring provides an enhanced implementation that - addresses this need. Named TomcatInstrumentableClassLoader, the loader works - on Tomcat 5.0 and above and can be registered individually for each web application - as follows: - + Apache Tomcat's default class loader + does not support class transformation which is why Spring provides an enhanced implementation that + addresses this need. Named TomcatInstrumentableClassLoader, the loader works + on Tomcat 5.0 and above and can be registered individually for each web application + as follows: + Tomcat 6.0.x or higher @@ -3774,23 +3779,23 @@ http://www.springframework.org/schema/context </Context> Apache Tomcat 6.0.x (similar to 5.0.x/5.5.x) series supports several context locations: - - server configuration file - $CATALINA_HOME/conf/server.xml - default context configuration - $CATALINA_HOME/conf/context.xml - that - affects all deployed web applications - per-web application configuration which can be deployed either on the server-side at - $CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml or embedded inside - the web-app archive at META-INF/context.xml - + + server configuration file - $CATALINA_HOME/conf/server.xml + default context configuration - $CATALINA_HOME/conf/context.xml - that + affects all deployed web applications + per-web application configuration which can be deployed either on the server-side at + $CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml or embedded inside + the web-app archive at META-INF/context.xml + For efficiency, the embedded per-web-app configuration style is recommended because it will impact only applications that use the custom class loader and does not require any changes to the server configuration. - See the Tomcat 6.0.x documentation + See the Tomcat 6.0.x documentation for more details about available context locations. - - + + Tomcat 5.0.x/5.5.x @@ -3813,18 +3818,18 @@ http://www.springframework.org/schema/context </Context> Tomcat 5.0.x and 5.5.x series supports several context locations: - - server configuration file - $CATALINA_HOME/conf/server.xml - default context configuration - $CATALINA_HOME/conf/context.xml - that - affects all deployed web applications - per-web application configuration which can be deployed either on the server-side at - $CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml or embedded inside - the web-app archive at META-INF/context.xml - - For efficiency, the embedded web-app configuration style is recommended - recommended because it will impact only applications that use the class loader. See the Tomcat 5.x documentation + recommended because it will impact only applications that use the class loader. See the Tomcat 5.x documentation for more details about available context locations. Tomcat versions prior to 5.5.20 contained a bug in the @@ -3832,9 +3837,9 @@ TR: REVISED, PLS REVIEW. Chnaged the last one to *inside*--> is recommended Loader tag inside server.xml configuration, regardless of whether a class loader is specified or whether it is the official or a custom - one. See Tomcat's bugzilla for more - details. + one. See Tomcat's bugzilla for more + details. In Tomcat 5.5.x, versions 5.5.20 or later, you should set useSystemClassLoaderAsParent to @@ -3848,9 +3853,9 @@ TR: REVISED, PLS REVIEW. Chnaged the last one to *inside*--> is recommended </Context>This setting is not needed on Tomcat 6 or higher. - + - + Alternatively, consider the use of the Spring-provided generic @@ -3859,7 +3864,7 @@ TR: REVISED, PLS REVIEW. Chnaged the last one to *inside*--> is recommended applications, no matter what ClassLoader they happen to run on.
-
+
WebLogic, WebSphere, OC4J, Resin, GlassFish, JBoss Recent versions of BEA WebLogic (version 10 and above), IBM WebSphere Application Server (version 7 and above), @@ -3871,17 +3876,17 @@ TR: REVISED, PLS REVIEW. Chnaged the last one to *inside*--> is recommended need to modify the launch script to add -javaagent:path/to/spring-instrument.jar. - Note that GlassFish instrumentation-capable ClassLoader is available only in its EAR environment. + Note that GlassFish instrumentation-capable ClassLoader is available only in its EAR environment. For GlassFish web applications, follow the Tomcat setup instructions as outlined above. - + Note that on JBoss 6.x, the app server scanning needs to be disabled to prevent it from loading the classes before the application actually starts. A quick workaround is to add to your artifact a file named WEB-INF/jboss-scanning.xml with the following content: - + <scanning xmlns="urn:jboss:scanning:1.0"/>
- -
+ +
Generic Java applications When class instrumentation is required in environments that do not support or @@ -3892,28 +3897,28 @@ TR: REVISED, PLS REVIEW. Chnaged the last one to *inside*--> is recommended which requires a Spring-specific (but very general) VM agent, org.springframework.instrument-{version}.jar (previously named spring-agent.jar). - + To use it, you must start the virtual machine with the Spring agent, by supplying the following JVM options: -javaagent:/path/to/org.springframework.instrument-{version}.jar - - + + Note that this requires modification of the VM launch script which may prevent you from using this in application server environments (depending on your operation policies). Additionally, the JDK agent will instrument the entire VM which can prove expensive. - For performance reasons, it is recommended to use this configuration only if your target environment - (such as Jetty) does not have (or does not support) a dedicated LTW. + For performance reasons, it is recommended to use this configuration only if your target environment + (such as Jetty) does not have (or does not support) a dedicated LTW.
- +
-
+
Further Resources - More information on AspectJ can be found on the AspectJ website. + More information on AspectJ can be found on the AspectJ website. The book Eclipse AspectJ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a comprehensive introduction and diff --git a/src/reference/docbook/beans-annotation-config.xml b/src/reference/docbook/beans-annotation-config.xml index 64d6af9933..f33427b51b 100644 --- a/src/reference/docbook/beans-annotation-config.xml +++ b/src/reference/docbook/beans-annotation-config.xml @@ -1,8 +1,12 @@ -
+ 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"> Annotation-based container configuration @@ -25,8 +29,8 @@ linkend="beans-java">JavaConfig 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 SpringSource Tool Suite. + supported by the SpringSource Tool Suite. 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 @Inject and @Named. Details about those annotations can be found in the relevant section. Annotation injection is performed + >relevant section. Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches. - As always, you can register them as individual bean definitions, but + 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 context namespace): @@ -72,16 +76,16 @@ </beans> - (The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, as - well as the aforementioned RequiredAnnotationBeanPostProcessor.) + (The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, as + well as the aforementioned RequiredAnnotationBeanPostProcessor.) <context:annotation-config/> only looks for @@ -95,7 +99,7 @@ information. -
+
<interfacename>@Required</interfacename> The @Required annotation applies to @@ -124,14 +128,14 @@ and values even when you use the class outside of a container.
-
+
<interfacename>@Autowired</interfacename> As expected, you can apply the @Autowired annotation to "traditional" setter methods: - + public class SimpleMovieLister { @@ -145,13 +149,13 @@ // ... } - + JSR 330's @Inject annotation can be used in place of Spring's @Autowired annotation in the examples below. See here for more details - - + + You can also apply the annotation to methods with arbitrary names and/or multiple arguments: @@ -310,7 +314,7 @@
-
+
Fine-tuning annotation-based autowiring with qualifiers Because autowiring by type may lead to multiple candidates, it is @@ -635,12 +639,12 @@ public @interface MovieQualifier { </beans>
-
+
<classname>CustomAutowireConfigurer</classname> - The CustomAutowireConfigurer is a + The CustomAutowireConfigurer is a BeanFactoryPostProcessor that enables you to register your own custom qualifier annotation types even if they are not annotated with Spring's @Qualifier @@ -675,7 +679,7 @@ public @interface MovieQualifier { will be selected.
-
+
<interfacename>@Resource</interfacename> Spring also supports injection using the JSR-250 @@ -719,9 +723,9 @@ public @interface MovieQualifier { The name provided with the annotation is resolved as a bean name by the ApplicationContext of which the CommonAnnotationBeanPostProcessor is aware. The - names can be resolved through JNDI if you configure Spring's SimpleJndiBeanFactory explicitly. + names can be resolved through JNDI if you configure Spring's SimpleJndiBeanFactory 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. @@ -760,7 +764,7 @@ public @interface MovieQualifier { }
-
+
<interfacename>@PostConstruct</interfacename> and <interfacename>@PreDestroy</interfacename> diff --git a/src/reference/docbook/beans-classpath-scanning.xml b/src/reference/docbook/beans-classpath-scanning.xml index ac61cfc3e9..eea20cb454 100644 --- a/src/reference/docbook/beans-classpath-scanning.xml +++ b/src/reference/docbook/beans-classpath-scanning.xml @@ -1,8 +1,12 @@ -
+ 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"> Classpath scanning and managed components Most examples in this chapter use XML to specify the configuration @@ -22,9 +26,9 @@ definitions registered with the container. - Starting with Spring 3.0, many features provided by the Spring JavaConfig - project are part of the core Spring Framework. This allows you to + Starting with Spring 3.0, many features provided by the Spring JavaConfig + project 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 @Configuration, @Bean, @@ -33,7 +37,7 @@ to use these new features. -
+
<interfacename>@Component</interfacename> and further stereotype annotations @@ -73,7 +77,7 @@ persistence layer.
-
+
Automatically detecting classes and registering bean definitions @@ -155,7 +159,7 @@ public class JpaMovieFinder implements MovieFinder { -->
-
+
Using filters to customize scanning By default, classes annotated with @@ -172,7 +176,7 @@ public class JpaMovieFinder implements MovieFinder { expression attributes. The following table describes the filtering options. - +
Filter Types @@ -268,7 +272,7 @@ public class JpaMovieFinder implements MovieFinder { -
+
Defining bean metadata within components Spring components can also contribute bean definition metadata to the @@ -358,7 +362,7 @@ public class FactoryMethodComponent { semantics.
-
+
Naming autodetected components When a component is autodetected as part of the scanning process, its @@ -390,9 +394,9 @@ public class MovieFinderImpl implements MovieFinder { If you do not want to rely on the default bean-naming strategy, you - can provide a custom bean-naming strategy. First, implement the BeanNameGenerator interface, and + can provide a custom bean-naming strategy. First, implement the BeanNameGenerator interface, and be sure to include a default no-arg constructor. Then, provide the fully-qualified class name when configuring the scanner: @@ -410,7 +414,7 @@ public class MovieFinderImpl implements MovieFinder { is responsible for wiring.
-
+
Providing a scope for autodetected components As with Spring-managed components in general, the default and most @@ -427,9 +431,9 @@ public class MovieFinderImpl implements MovieFinder { To provide a custom strategy for scope resolution rather than - relying on the annotation-based approach, implement the ScopeMetadataResolver interface, + relying on the annotation-based approach, implement the ScopeMetadataResolver interface, and be sure to include a default no-arg constructor. Then, provide the fully-qualified class name when configuring the scanner: @@ -457,7 +461,7 @@ public class MovieFinderImpl implements MovieFinder { </beans>
-
+
Providing qualifier metadata with annotations The @Qualifier annotation is discussed diff --git a/src/reference/docbook/beans-context-additional.xml b/src/reference/docbook/beans-context-additional.xml index 7b53fb60a0..471345ea21 100644 --- a/src/reference/docbook/beans-context-additional.xml +++ b/src/reference/docbook/beans-context-additional.xml @@ -1,8 +1,12 @@ -
+ 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"> Additional Capabilities of the <interfacename>ApplicationContext</interfacename> @@ -12,9 +16,9 @@ org.springframework.beans.factory package provides basic functionality for managing and manipulating beans, including in a programmatic way. The org.springframework.context package - adds the ApplicationContext interface, which + adds the ApplicationContext interface, which extends the BeanFactory interface, in addition to extending other interfaces to provide additional functionality in a more application framework-oriented style. Many @@ -56,7 +60,7 @@ -
+
Internationalization using <interfacename>MessageSource</interfacename> @@ -181,12 +185,12 @@ argument.required=The '{0}' argument is required. <beans> - <!-- this MessageSource is being used in a web application --> + <!-- this MessageSource is being used in a web application --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="exceptions"/> </bean> - <!-- lets inject the above MessageSource into this POJO --> + <!-- lets inject the above MessageSource into this POJO --> <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.
-
+
Standard and Custom Events Event handling in the @@ -281,7 +285,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.Observer design pattern. Spring provides the following standard events: -
+
Built-in Events @@ -492,16 +496,16 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.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 Spring - Integration project provides complete support for building - lightweight, pattern-oriented, event-driven architectures that build upon + separately-maintained Spring + Integration project provides complete support for building + lightweight, pattern-oriented, event-driven architectures that build upon the well-known Spring programming model. -
+
Convenient access to low-level resources 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.
-
+
Convenient <interfacename>ApplicationContext</interfacename> instantiation for web applications @@ -585,7 +589,7 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.<!-- or use the ContextLoaderServlet instead of the above listener +<!-- or use the ContextLoaderServlet instead of the above listener <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.
-
+
Deploying a Spring ApplicationContext as a J2EE RAR file 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.TaskExecutor abstraction. - Check out the JavaDoc of the SpringContextResourceAdapter class for the configuration details + Check out the JavaDoc of the SpringContextResourceAdapter class for the configuration details involved in RAR deployment. For a simple deployment of a Spring ApplicationContext as a diff --git a/src/reference/docbook/beans-customizing.xml b/src/reference/docbook/beans-customizing.xml index 51b5c36e27..acca5514a7 100644 --- a/src/reference/docbook/beans-customizing.xml +++ b/src/reference/docbook/beans-customizing.xml @@ -1,11 +1,16 @@ -
+ 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"> Customizing the nature of a bean -
+
Lifecycle callbacks @@ -41,7 +45,7 @@ injection and Setter-based dependency injection. -
+
Constructor-based dependency injection Constructor-based DI is accomplished by the @@ -58,18 +62,18 @@ public class SimpleMovieLister { - // the SimpleMovieLister has a dependency on a MovieFinder + // the SimpleMovieLister has a dependency on a MovieFinder private MovieFinder movieFinder; - // a constructor so that the Spring container can 'inject' a MovieFinder + // a constructor so that the Spring container can 'inject' a MovieFinder public SimpleMovieLister(MovieFinder movieFinder) { this.movieFinder = movieFinder; } - // business logic that actually 'uses' the injected MovieFinder is omitted... + // business logic that actually 'uses' the injected MovieFinder is omitted... } -
+
Constructor argument resolution Constructor argument resolution matching occurs using the @@ -129,7 +133,7 @@ public class ExampleBean { } } -
+
Constructor argument type matching In the preceding scenario, the container @@ -143,7 +147,7 @@ public class ExampleBean { </bean>
-
+
Constructor argument index Use the index attribute to specify explicitly @@ -160,7 +164,7 @@ public class ExampleBean { 0 based.
-
+
Constructor argument name 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 - @ConstructorProperties + @ConstructorProperties JDK annotation to explicitly name your constructor arguments. The sample class would then have to look as follows: @@ -196,7 +200,7 @@ public class ExampleBean {
-
+
Setter-based dependency injection Setter-based DI is accomplished by the @@ -211,15 +215,15 @@ public class ExampleBean { public class SimpleMovieLister { - // the SimpleMovieLister has a dependency on the MovieFinder + // the SimpleMovieLister has a dependency on the MovieFinder private MovieFinder movieFinder; - // a setter method so that the Spring container can 'inject' a MovieFinder + // a setter method so that the Spring container can 'inject' a MovieFinder public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } - // business logic that actually 'uses' the injected MovieFinder is omitted... + // business logic that actually 'uses' the injected MovieFinder is omitted... } The ApplicationContext supports @@ -265,7 +269,7 @@ public class ExampleBean {
-
+
Dependency resolution process The container performs bean dependency resolution as follows: @@ -371,7 +375,7 @@ public class ExampleBean { callback method) are invoked.
-
+
Examples of dependency injection The following example uses XML-based configuration metadata for @@ -380,7 +384,7 @@ public class ExampleBean { <bean id="exampleBean" class="examples.ExampleBean"> -<!-- setter injection using the nested <ref/> element --> +<!-- setter injection using the nested <ref/> element --> <property name="beanOne"><ref bean="anotherExampleBean"/></property> <!-- setter injection using the neater 'ref' attribute --> @@ -416,7 +420,7 @@ public class ExampleBean { <bean id="exampleBean" class="examples.ExampleBean"> -<!-- constructor injection using the nested <ref/> element --> +<!-- constructor injection using the nested <ref/> element --> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> @@ -494,7 +498,7 @@ public class ExampleBean {
-
+
Dependencies and configuration in detail As mentioned in the previous section, you can define bean properties @@ -505,7 +509,7 @@ public class ExampleBean { <constructor-arg/> elements for this purpose. -
+
Straight values (primitives, <literal>Strings</literal>, and so on) @@ -519,7 +523,7 @@ public class ExampleBean { <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> -<!-- results in a setDriverClassName(String) call --> +<!-- results in a setDriverClassName(String) call --> <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 { The preceding XML is more succinct; however, typos are discovered at - runtime rather than design time, unless you use an IDE such as IntelliJ IDEA or the SpringSource Tool - Suite (STS) that support automatic property completion when you + runtime rather than design time, unless you use an IDE such as IntelliJ IDEA or the SpringSource Tool + Suite (STS) that support automatic property completion when you create bean definitions. Such IDE assistance is highly recommended. @@ -560,7 +564,7 @@ public class ExampleBean { <bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> - <!-- typed as a java.util.Properties --> + <!-- typed as a java.util.Properties --> <property name="properties"> <value> jdbc.driver.className=com.mysql.jdbc.Driver @@ -577,7 +581,7 @@ public class ExampleBean { favor the use of the nested <value/> element over the value attribute style. -
+
The <literal>idref</literal> element The idref 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. <property name="targetName"> - <!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown --> + <!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown --> <idref local="theTargetBean"/> </property> @@ -635,7 +639,7 @@ public class ExampleBean {
-
+
References to other beans (collaborators) The ref 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 - bean,local, or + bean,local, or parent attributes. Specifying the target bean through the bean @@ -701,7 +705,7 @@ public class ExampleBean { </bean>
-
+
Inner beans A <bean/> element inside the @@ -729,7 +733,7 @@ public class ExampleBean { collaborating beans other than into the enclosing bean.
-
+
Collections In the <list/>, @@ -741,7 +745,7 @@ public class ExampleBean { Properties, respectively. <bean id="moreComplexObject" class="example.ComplexObject"> -<!-- results in a setAdminEmails(java.util.Properties) call --> +<!-- results in a setAdminEmails(java.util.Properties) call --> <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> -<!-- results in a setSomeList(java.util.List) call --> +<!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> -<!-- results in a setSomeMap(java.util.Map) call --> +<!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> @@ -777,7 +781,7 @@ public class ExampleBean { bean | ref | idref | list | set | map | props | value | null -
+
Collection merging As of Spring 2.0, the container supports the @@ -859,7 +863,7 @@ support=support@example.co.uk the container uses internally.
-
+
Limitations of collection merging You cannot merge different collection types (such as a @@ -873,7 +877,7 @@ support=support@example.co.uk in Spring 2.0 and later.
-
+
Strongly-typed collection (Java 5+ only) In Java 5 and later, you can use strongly typed collections (using @@ -920,7 +924,7 @@ support=support@example.co.uk
-
+
Null and empty string values Spring @@ -946,7 +950,7 @@ support=support@example.co.uk exampleBean.setEmail(null).
-
+
XML shortcut with the p-namespace The p-namespace enables you to use the bean @@ -1030,26 +1034,26 @@ support=support@example.co.uk time.
- -
+ +
XML shortcut with the c-namespace - - Similar to the , the c-namespace, newly introduced in Spring 3.1, + + Similar to the , the c-namespace, newly introduced in Spring 3.1, allows usage of inlined attributes for configuring the constructor arguments rather then nested constructor-arg elements. - + Let's review the examples from with the c namespace: - + <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 </beans> - The c: namespace uses the same conventions as the p: one (trailing -ref 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). - - 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: + The c: namespace uses the same conventions as the p: one (trailing -ref 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). + + 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: <-- 'c-namespace' index declaration --> <bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz"> - Due to the XML grammar, the index notation requires the presence of the leading _ as XML attribute names cannot start - with a number (even though some IDE allow it). - - In practice, the constructor resolution mechanism is quite efficient in matching arguments so - unless one really needs to, we recommend using the name notation through-out your configuration. + Due to the XML grammar, the index notation requires the presence of the leading _ as XML attribute names cannot start + with a number (even though some IDE allow it). + + In practice, the constructor resolution mechanism is quite efficient in matching arguments so + unless one really needs to, we recommend using the name notation through-out your configuration.
-
+
Compound property names You can use compound or nested property names when you set bean @@ -1102,7 +1106,7 @@ support=support@example.co.uk
-
+
Using <literal>depends-on</literal> If a bean is a dependency of another that usually means that one bean @@ -1144,7 +1148,7 @@ support=support@example.co.uk
-
+
Lazy-initialized beans<!--Changed to lazy-initialized from lazily instantiated because attribute is lazy-init, and there was a lot of inconsistency. --> @@ -1190,7 +1194,7 @@ support=support@example.co.uk </beans>
-
+
Autowiring collaborators @@ -1225,7 +1229,7 @@ support=support@example.co.uk five modes. You specify autowiring per bean and thus can choose which ones to autowire. -
+
Autowiring modes @@ -1301,7 +1305,7 @@ support=support@example.co.uk You can combine autowire behavior with dependency checking, which is performed after autowiring completes. -
+
Limitations and disadvantages of autowiring Autowiring works best when it is used consistently across a project. @@ -1377,7 +1381,7 @@ support=support@example.co.uk
-
+
Excluding a bean from autowiring On a per-bean basis, you can exclude a bean from autowiring. In @@ -1410,7 +1414,7 @@ support=support@example.co.uk
-
+
Method injection In most application scenarios, most beans in the container are // grab a new instance of the appropriate Command + // grab a new instance of the appropriate Command Command command = createCommand(); - // set the state on the (hopefully brand new) Command instance + // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } @@ -1472,11 +1476,11 @@ public class CommandManager implements ApplicationContextAware { You can read more about the motivation for Method Injection in - this blog entry. + this blog entry. -
+
Lookup method injection @@ -1519,9 +1523,9 @@ public class CommandManager implements ApplicationContextAware { public abstract class CommandManager { public Object process(Object commandState) { - // grab a new instance of the appropriate Command interface + // grab a new instance of the appropriate Command interface Command command = createCommand(); - // set the state on the (hopefully brand new) Command instance + // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } @@ -1546,7 +1550,7 @@ public abstract class CommandManager { <!-- inject dependencies here as required --> </bean> -<!-- commandProcessor uses statefulCommandHelper --> +<!-- commandProcessor uses statefulCommandHelper --> <bean id="commandManager" class="fiona.apple.CommandManager"> <lookup-method name="createCommand" bean="command"/> </bean> @@ -1569,14 +1573,14 @@ public abstract class CommandManager { ObjectFactoryCreatingFactoryBean, 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 blog entry for additional information + classes as well as this blog entry for additional information ServiceLocatorFactoryBean.
-
+
Arbitrary method replacement A less useful form of method injection than lookup method Injection @@ -1604,8 +1608,8 @@ public String computeValue(String input) { org.springframework.beans.factory.support.MethodReplacer interface provides the new method definition. - /** meant to be used to override the existing computeValue(String) - implementation in MyValueCalculator + /** meant to be used to override the existing computeValue(String) + implementation in MyValueCalculator */ public class ReplacementComputeValue implements MethodReplacer { diff --git a/src/reference/docbook/beans-extension-points.xml b/src/reference/docbook/beans-extension-points.xml index e45525b23b..e8e2a114ed 100644 --- a/src/reference/docbook/beans-extension-points.xml +++ b/src/reference/docbook/beans-extension-points.xml @@ -1,8 +1,12 @@ -
+ 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"> Container Extension Points 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. -
+
Customizing beans using a <interfacename>BeanPostProcessor</interfacename> @@ -85,7 +89,7 @@ Bean post-processors can be deployed in the container just like any other beans. - + Programmatically registering <interfacename>BeanPostProcessors </interfacename> @@ -137,7 +141,7 @@ BeanPostProcessors in an ApplicationContext. -
+
Example: Hello World, <interfacename>BeanPostProcessor</interfacename>-style @@ -187,7 +191,7 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor <!-- when the above bean (messenger) is instantiated, this custom - BeanPostProcessor implementation will output the fact to the system console + BeanPostProcessor implementation will output the fact to the system console --> <bean class="scripting.InstantiationTracingBeanPostProcessor"/> @@ -224,7 +228,7 @@ public final class Boot { org.springframework.scripting.groovy.GroovyMessenger@272961
-
+
Example: The <classname>RequiredAnnotationBeanPostProcessor</classname> @@ -239,7 +243,7 @@ org.springframework.scripting.groovy.GroovyMessenger@272961
-
+
Customizing configuration metadata with a <interfacename>BeanFactoryPostProcessor</interfacename> @@ -299,7 +303,7 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 BeanFactoryPostProcessor can also be used, for example, to register custom property editors. - + An ApplicationContext automatically detects any beans that are deployed into it that implement the @@ -314,14 +318,14 @@ org.springframework.scripting.groovy.GroovyMessenger@272961 for lazy initialization. If no other bean references a Bean(Factory)PostProcessor, 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 Bean(Factory)PostProcessor will be instantiated eagerly even if you set the default-lazy-init attribute to true on the declaration of your <beans /> element. -
+
Example: the <interfacename>PropertyPlaceholderConfigurer</interfacename> @@ -392,15 +396,15 @@ jdbc.password=root - - never (0): Never check system properties - - - fallback (1): Check system properties if not resolvable in the specified properties files. This is the default. - - - override (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source. - + + never (0): Never check system properties + + + fallback (1): Check system properties if not resolvable in the specified properties files. This is the default. + + + override (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source. + @@ -434,7 +438,7 @@ jdbc.password=root
-
+
Example: the <classname>PropertyOverrideConfigurer</classname> @@ -495,7 +499,7 @@ dataSource.url=jdbc:mysql:mydb
-
+
Customizing instantiation logic with a <interfacename>FactoryBean</interfacename> diff --git a/src/reference/docbook/beans-java.xml b/src/reference/docbook/beans-java.xml index f81a44fcb2..8db15fb834 100644 --- a/src/reference/docbook/beans-java.xml +++ b/src/reference/docbook/beans-java.xml @@ -1,11 +1,15 @@ -
+ 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"> Java-based container configuration -
+
Basic concepts: <literal>@Configuration</literal> and <literal>@Bean</literal> @@ -41,7 +45,7 @@ public class AppConfig { spring container using Java-based configuration.
-
+
Instantiating the Spring container using <literal>AnnotationConfigApplicationContext</literal> @@ -63,7 +67,7 @@ public class AppConfig { @Inject are used within those classes where necessary. -
+
Simple construction In much the same way that Spring XML files are used as input when @@ -92,7 +96,7 @@ public class AppConfig { @Autowired.
-
+
Building the container programmatically using <literal>register(Class<?>...)</literal> @@ -111,7 +115,7 @@ public class AppConfig { }
-
+
Enabling component scanning with <literal>scan(String...)</literal> @@ -148,7 +152,7 @@ public class AppConfig {
-
+
Support for web applications with <literal>AnnotationConfigWebApplicationContext</literal> @@ -214,10 +218,10 @@ public class AppConfig {
-
+
Composing Java-based configurations -
+
Using the <literal>@Import</literal> annotation Much as the <import/> element is used @@ -250,7 +254,7 @@ public class ConfigB { a potentially large number of @Configuration classes during construction. -
+
Injecting dependencies on imported <literal>@Bean</literal> definitions @@ -304,7 +308,7 @@ public static void main(String[] args) { transferService.transfer(100.00, "A123", "C456"); } -
+
Fully-qualifying imported beans for ease of navigation In the scenario above, using @Autowired works @@ -314,8 +318,8 @@ public static void main(String[] args) { ServiceConfig, how do you know exactly where the @Autowired AccountRepository bean is declared? It's not explicit in the code, and this may be just fine. Remember - that the SpringSource Tool Suite provides tooling that can render + that the SpringSource Tool Suite 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 AccountRepository type, and will quickly @@ -386,7 +390,7 @@ public static void main(String[] args) {
-
+
Combining Java and XML configuration Spring's @Configuration class support does not @@ -400,7 +404,7 @@ public static void main(String[] args) { @ImportResource annotation to import XML as needed. -
+
XML-centric use of <literal>@Configuration</literal> classes @@ -413,7 +417,7 @@ public static void main(String[] args) { @Configuration classes in this kind of "XML-centric" situation. -
+
Declaring <literal>@Configuration</literal> classes as plain Spring <literal><bean/></literal> elements @@ -476,7 +480,7 @@ jdbc.password=
-
+
Using <literal><context:component-scan/></literal> to pick up <literal>@Configuration</literal> classes @@ -506,7 +510,7 @@ jdbc.password=
-
+
<literal>@Configuration</literal> class-centric use of XML with <literal>@ImportResource</literal> @@ -544,7 +548,7 @@ jdbc.password=
-
+
Using the <interfacename>@Bean</interfacename> annotation @Bean is a method-level annotation and @@ -562,7 +566,7 @@ jdbc.password= @Configuration-annotated or in a @Component-annotated class. -
+
Declaring a bean To declare a bean, simply annotate a method with the @@ -595,7 +599,7 @@ transferService -> com.acme.TransferServiceImpl
-
+
Injecting dependencies When @Beans have dependencies on one @@ -620,7 +624,7 @@ public class AppConfig { to bar via constructor injection.
-
+
Receiving lifecycle callbacks Beans declared in a @@ -697,10 +701,10 @@ public class AppConfig {
-
+
Specifying bean scope -
+
Using the <interfacename>@Scope</interfacename> annotation @@ -724,7 +728,7 @@ public class MyConfiguration { }
-
+
<code>@Scope and scoped-proxy</code> Spring offers a convenient way of working with scoped dependencies @@ -757,7 +761,7 @@ public Service userService() { }
-
+
Lookup method injection As noted earlier,
-
+
Customizing bean naming By default, configuration classes use a @@ -825,7 +829,7 @@ public class AppConfig { -
+
Bean aliasing As discussed in , it is sometimes @@ -845,7 +849,7 @@ public class AppConfig {
-
+
Further information about how Java-based configuration works internally diff --git a/src/reference/docbook/beans-scopes.xml b/src/reference/docbook/beans-scopes.xml index e70dc65108..abba10043f 100644 --- a/src/reference/docbook/beans-scopes.xml +++ b/src/reference/docbook/beans-scopes.xml @@ -1,8 +1,12 @@ -
+ 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"> Bean scopes When you create a bean definition, you create a @@ -25,7 +29,7 @@ The following scopes are supported out of the box. You can also create a custom scope. -
+
Bean scopes @@ -94,14 +98,14 @@ As of Spring 3.0, a thread scope is available, but is not registered by default. For more information, see the - documentation for SimpleThreadScope. For instructions on how to register this or + documentation for SimpleThreadScope. For instructions on how to register this or any other custom scope, see . -
+
The singleton scope Only one shared instance of a singleton bean is @@ -146,7 +150,7 @@ <bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>
-
+
The prototype scope The non-singleton, prototype scope of bean deployment results in the @@ -175,7 +179,7 @@ The following example defines a bean as a prototype in XML: - <!-- using spring-beans-2.0.dtd --> + <!-- using spring-beans-2.0.dtd --> <bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/> In contrast to the other scopes, Spring does not manage the complete @@ -199,7 +203,7 @@ see .)
-
+
Singleton beans with prototype-bean dependencies When you use singleton-scoped beans with dependencies on prototype @@ -220,7 +224,7 @@ linkend="beans-factory-method-injection"/>
-
+
Request, session, and global session scopes The request, session, and @@ -233,7 +237,7 @@ IllegalStateException complaining about an unknown bean scope. -
+
Initial web configuration To support the scoping of beans at the request, @@ -301,7 +305,7 @@ call chain.
-
+
Request scope Consider the following bean definition: @@ -320,7 +324,7 @@ is scoped to the request is discarded.
-
+
Session scope Consider the following bean definition: @@ -345,7 +349,7 @@ Session is also discarded.
-
+
Global session scope Consider the following bean definition: @@ -369,7 +373,7 @@ no error is raised.
-
+
Scoped beans as dependencies 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"> - <!-- an HTTP Session-scoped bean exposed as a proxy --> + <!-- an HTTP Session-scoped bean exposed as a proxy --> <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <!-- instructs the container to proxy the surrounding bean --> @@ -413,7 +417,7 @@ <!-- a singleton-scoped bean injected with a proxy to the above bean --> <bean id="userService" class="com.foo.SimpleUserService"> - <!-- a reference to the proxied userPreferences bean --> + <!-- a reference to the proxied userPreferences bean --> <property name="userPreferences" ref="userPreferences"/> </bean> @@ -493,7 +497,7 @@ <property name="userPreferences" ref="userPreferences"/> </bean> -
+
Choosing the type of proxy to create 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. - <!-- DefaultUserPreferences implements the UserPreferences interface --> + <!-- DefaultUserPreferences implements the UserPreferences interface --> <bean id="userPreferences" class="com.foo.DefaultUserPreferences" scope="session"> <aop:scoped-proxy proxy-target-class="false"/> </bean> @@ -532,7 +536,7 @@
-
+
Custom scopes As of Spring 2.0, the bean scoping mechanism is extensible. You can @@ -541,7 +545,7 @@ override the built-in singleton and prototype scopes. -
+
Creating a custom scope 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 Scope implementations that are supplied with the Spring Framework itself and - the Scope Javadoc, which explains the methods you need to implement + the Scope Javadoc, which explains the methods you need to implement in more detail. The Scope interface has four methods to get @@ -590,7 +594,7 @@ String getConversationId()
-
+
Using a custom scope After you write and test one or more custom diff --git a/src/reference/docbook/beans-standard-annotations.xml b/src/reference/docbook/beans-standard-annotations.xml index 44d06ead95..486d14830b 100644 --- a/src/reference/docbook/beans-standard-annotations.xml +++ b/src/reference/docbook/beans-standard-annotations.xml @@ -1,21 +1,25 @@ -
+ 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"> Using JSR 330 Standard Annotations - + 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. - + If you are using Maven, the javax.inject artifact is available in the standard Maven repository - (http://repo1.maven.org/maven2/javax/inject/javax.inject/1/). + (http://repo1.maven.org/maven2/javax/inject/javax.inject/1/). You can add the following dependency to your file pom.xml: - + <dependency> <groupId>javax.inject</groupId> @@ -23,8 +27,8 @@ <version>1</version> </dependency> - -
+ +
Dependency Injection with <interfacename>@Inject</interfacename> and <interfacename>@Named</interfacename> Instead of @Autowired, @@ -45,10 +49,10 @@ public class SimpleMovieLister { As with @Autowired, it is possible to use @Inject - 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 @Named annotation as follows: + If you would like to use a qualified name for the dependency that should be injected, + you should use the @Named annotation as follows: import javax.inject.Inject; import javax.inject.Named; @@ -62,18 +66,18 @@ public class SimpleMovieLister { this.movieFinder = movieFinder; } // ... -} - +} +
-
+
<interfacename>@Named</interfacename>: a standard equivalent to the <interfacename>@Component</interfacename> annotation Instead of @Component, @javax.inject.Named may be used as follows: import javax.inject.Inject; import javax.inject.Named; - + @Named("movieListener") public class SimpleMovieLister { @@ -84,7 +88,7 @@ public class SimpleMovieLister { this.movieFinder = movieFinder; } // ... -} +} @@ -94,7 +98,7 @@ can be used in a similar fashion: 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: <beans> <context:component-scan base-package="org.example"/> -</beans> +</beans>
-
+
Limitations of the standard approach - When working with standard annotations, it is important to know that - some significant features are not available as shown in the table below: - -
+ When working with standard annotations, it is important to know that + some significant features are not available as shown in the table below: + +
Spring annotations vs. standard annotations @@ -156,46 +160,46 @@ component-scanning in the exact same way as when using Spring annotations: @Scope("singleton") @Singleton - - The JSR-330 default scope is like Spring's prototype. - However, in order to keep it consistent with Spring's general defaults, - a JSR-330 bean declared in the Spring container is a - singleton by default. In order to use a - scope other than singleton, you should use Spring's - @Scope annotation. - - - javax.inject also provides a - @Scope annotation. - Nevertheless, this one is only intended to be used for creating your own annotations. - + + The JSR-330 default scope is like Spring's prototype. + However, in order to keep it consistent with Spring's general defaults, + a JSR-330 bean declared in the Spring container is a + singleton by default. In order to use a + scope other than singleton, you should use Spring's + @Scope annotation. + + + javax.inject also provides a + @Scope annotation. + Nevertheless, this one is only intended to be used for creating your own annotations. + - + @Qualifier @Named - + @Value no equivalent - + @Required no equivalent - + @Lazy no equivalent - - + +
- -
+ +
diff --git a/src/reference/docbook/beans.xml b/src/reference/docbook/beans.xml index 00ad057fe6..05f32bd57c 100644 --- a/src/reference/docbook/beans.xml +++ b/src/reference/docbook/beans.xml @@ -1,11 +1,15 @@ - + 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"> The IoC container -
+
Introduction to the Spring IoC container and beans 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 The org.springframework.beans and org.springframework.context packages are the basis for - Spring Framework's IoC container. The BeanFactory interface provides an advanced + Spring Framework's IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. - ApplicationContext is a sub-interface of + ApplicationContext is a sub-interface of BeanFactory. 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.
-
+
Container overview The interface @@ -79,11 +83,11 @@ The footnote should x-ref to first section in that chapter but I can't find the Several implementations of the ApplicationContext interface are supplied out-of-the-box with Spring. In standalone applications it is common to - create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. + create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. 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 web.xml file of the application will typically suffice (see ). - If you are using the SpringSource Tool Suite Eclipse-powered development environment - or Spring Roo this + If you are using the SpringSource Tool Suite Eclipse-powered development environment + or Spring Roo this boilerplate configuration can be easily created with few mouse clicks or keystrokes. @@ -115,7 +119,7 @@ The footnote should x-ref to first section in that chapter but I can't find the The Spring IoC container -
+
Configuration metadata 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 Java-based configuration: - Starting with Spring 3.0, many features provided by the Spring JavaConfig - project became part of the core Spring Framework. Thus you + Starting with Spring 3.0, many features provided by the Spring JavaConfig + project 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 @Configuration, @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.
-
+
Instantiating a container 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 In the preceding example, the service layer consists of the class PetStoreServiceImpl, and two data access objects of the type SqlMapAccountDao and SqlMapItemDao - are based on the iBatis + are based on the iBatis Object/Relational mapping framework. The property name element refers to the name of the JavaBean property, and the ref 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 Dependencies. -
+
Composing XML-based configuration metadata 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
-
+
Using the container The ApplicationContext is the @@ -385,7 +389,7 @@ List userList = service.getUsernameList();
-
+
Bean overview A Spring IoC container manages one or more beans. @@ -426,7 +430,7 @@ List userList = service.getUsernameList(); This metadata translates to a set of properties that make up each bean definition. - +
The bean definition @@ -522,7 +526,7 @@ List userList = service.getUsernameList(); applications work solely with beans defined through metadata bean definitions. -
+
Naming beans Every bean has one or more identifiers. These identifiers must be @@ -548,7 +552,7 @@ List userList = service.getUsernameList(); 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 ref element or ref element or Service Locator style lookup, you must provide a name. Motivations for not supplying a name are related to using inner beans @@ -570,7 +574,7 @@ List userList = service.getUsernameList(); applying advice to a set of beans related by name. -
+
Aliasing a bean outside the bean definition In a bean definition itself, you can supply more than one name for @@ -617,7 +621,7 @@ List userList = service.getUsernameList();
-
+
Instantiating beans 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. -
+
Instantiation with a constructor When you create a bean by the constructor approach, all normal @@ -709,7 +713,7 @@ List userList = service.getUsernameList(); Dependencies.
-
+
Instantiation with a static factory method When defining a bean that you create with a static factory method, @@ -749,7 +753,7 @@ List userList = service.getUsernameList(); configuration in detail.
-
+
Instantiation using an instance factory method Similar to instantiation through a factory-method attribute. - <!-- the factory bean, which contains a method called createInstance() --> + <!-- the factory bean, which contains a method called createInstance() --> <bean id="serviceLocator" class="examples.DefaultServiceLocator"> <!-- inject any dependencies required by this locator bean --> </bean> @@ -835,15 +839,13 @@ List userList = service.getUsernameList();
- + - + -
+
Bean definition inheritance 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"/> - <!-- age will inherit the value of 1 from the parent bean definition--> + <!-- age will inherit the value of 1 from the parent bean definition--> </bean> The parent bean cannot be instantiated on its own because it is @@ -950,7 +952,7 @@ List userList = service.getUsernameList(); -
+
Registering a <interfacename>LoadTimeWeaver</interfacename> The LoadTimeWeaver is used by Spring to dynamically @@ -986,7 +988,7 @@ public class AppConfig { -
+
The BeanFactory The BeanFactory provides the underlying basis @@ -1007,7 +1009,7 @@ public class AppConfig { ApplicationContext and how one might access the IoC container directly through a classic singleton lookup. -
+
<interfacename>BeanFactory</interfacename> or <interfacename>ApplicationContext</interfacename>? @@ -1037,7 +1039,7 @@ public class AppConfig { ApplicationContext interfaces and implementations. -
Feature Matrix @@ -1113,7 +1115,7 @@ public class AppConfig { ConfigurableBeanFactory factory = new XmlBeanFactory(...); -// now register any needed BeanPostProcessor instances +// now register any needed BeanPostProcessor instances MyBeanPostProcessor postProcessor = new MyBeanPostProcessor(); factory.addBeanPostProcessor(postProcessor); @@ -1126,7 +1128,7 @@ factory.addBeanPostProcessor(postProcessor); XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml")); -// bring in some property values from a Properties file +// bring in some property values from a Properties file PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.setLocation(new FileSystemResource("jdbc.properties")); @@ -1144,7 +1146,7 @@ cfg.postProcessBeanFactory(factory); AOP. -
+
Glue code and the evil singleton It is best to write most application code in a dependency-injection @@ -1176,12 +1178,12 @@ cfg.postProcessBeanFactory(factory); 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 - ContextSingletonBeanFactoryLocator - locator that is described in this SpringSource team blog entry. + ContextSingletonBeanFactoryLocator + locator that is described in this SpringSource team blog entry.
diff --git a/src/reference/docbook/cache.xml b/src/reference/docbook/cache.xml index 7070103306..b96eaa3c91 100644 --- a/src/reference/docbook/cache.xml +++ b/src/reference/docbook/cache.xml @@ -1,129 +1,133 @@ - - Cache Abstraction + 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"> + Cache Abstraction -
- Introduction +
+ Introduction - Since version 3.1, Spring Framework provides support for transparently - adding caching into an existing Spring application. Similar to the transaction - support, the caching abstraction allows consistent use of various caching - solutions with minimal impact on the code. -
+ Since version 3.1, Spring Framework provides support for transparently + adding caching into an existing Spring application. Similar to the transaction + support, the caching abstraction allows consistent use of various caching + solutions with minimal impact on the code. +
-
- Understanding the cache abstraction +
+ Understanding the cache abstraction - - Cache vs Buffer - The terms "buffer" and "cache" tend to be used interchangeably; note however they represent different things. - A buffer is used traditionally as an intermediate temporary store for data between a fast and a slow entity. As one - party would have to wait for the other affecting performance, the buffer alleviates this by - allowing entire blocks of data to move at once rather then in small chunks. The data is written and read only once from - the buffer. Furthermore, the buffers are visible to at least one party which is aware of it. - A cache on the other hand by definition is hidden and neither party is aware that caching occurs.It as well improves - performance but does that by allowing the same data to be read multiple times in a fast fashion. + + Cache vs Buffer + The terms "buffer" and "cache" tend to be used interchangeably; note however they represent different things. + A buffer is used traditionally as an intermediate temporary store for data between a fast and a slow entity. As one + party would have to wait for the other affecting performance, the buffer alleviates this by + allowing entire blocks of data to move at once rather then in small chunks. The data is written and read only once from + the buffer. Furthermore, the buffers are visible to at least one party which is aware of it. + A cache on the other hand by definition is hidden and neither party is aware that caching occurs.It as well improves + performance but does that by allowing the same data to be read multiple times in a fast fashion. - A further explanation of the differences between two can be found - here. - + A further explanation of the differences between two can be found + here. + - At its core, the abstraction applies caching to Java methods, reducing thus the number of executions based on the - information available in the cache. That is, each time a targeted method is invoked, the abstraction - will apply a caching behavior checking whether the method has been already executed for the given arguments. If it has, - then the cached result is returned without having to execute the actual method; if it has not, then method is executed, the - result cached and returned to the user so that, the next time the method is invoked, the cached result is returned. - This way, expensive methods (whether CPU or IO bound) can be executed only once for a given set of parameters and the result - reused without having to actually execute the method again. The caching logic is applied transparently without any interference - to the invoker. + At its core, the abstraction applies caching to Java methods, reducing thus the number of executions based on the + information available in the cache. That is, each time a targeted method is invoked, the abstraction + will apply a caching behavior checking whether the method has been already executed for the given arguments. If it has, + then the cached result is returned without having to execute the actual method; if it has not, then method is executed, the + result cached and returned to the user so that, the next time the method is invoked, the cached result is returned. + This way, expensive methods (whether CPU or IO bound) can be executed only once for a given set of parameters and the result + reused without having to actually execute the method again. The caching logic is applied transparently without any interference + to the invoker. - Obviously this approach works only for methods that are guaranteed to return the same output (result) for a given input - (or arguments) no matter how many times it is being executed. + Obviously this approach works only for methods that are guaranteed to return the same output (result) for a given input + (or arguments) no matter how many times it is being executed. - To use the cache abstraction, the developer needs to take care of two aspects: - - caching declaration - identify the methods that need to be cached and their policy - cache configuration - the backing cache where the data is stored and read from - - + To use the cache abstraction, the developer needs to take care of two aspects: + + caching declaration - identify the methods that need to be cached and their policy + cache configuration - the backing cache where the data is stored and read from + + - Note that just like other services in Spring Framework, the caching service is an abstraction (not a cache implementation) and requires - the use of an actual storage to store the cache data - that is, the abstraction frees the developer from having to write the caching - logic but does not provide the actual stores. There are two integrations available out of the box, for JDK java.util.concurrent.ConcurrentMap - and Ehcache - see for more information on plugging in other cache stores/providers. -
+ Note that just like other services in Spring Framework, the caching service is an abstraction (not a cache implementation) and requires + the use of an actual storage to store the cache data - that is, the abstraction frees the developer from having to write the caching + logic but does not provide the actual stores. There are two integrations available out of the box, for JDK java.util.concurrent.ConcurrentMap + and Ehcache - see for more information on plugging in other cache stores/providers. +
-
- Declarative annotation-based caching +
+ Declarative annotation-based caching - For caching declaration, the abstraction provides two Java annotations: @Cacheable and @CacheEvict which allow methods - to trigger cache population or cache eviction. Let us take a closer look at each annotation: + For caching declaration, the abstraction provides two Java annotations: @Cacheable and @CacheEvict which allow methods + to trigger cache population or cache eviction. Let us take a closer look at each annotation: -
- <literal>@Cacheable</literal> annotation +
+ <literal>@Cacheable</literal> annotation - As the name implies, @Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache - so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method. In its simplest form, - the annotation declaration requires the name of the cache associated with the annotated method: + As the name implies, @Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache + so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method. In its simplest form, + the annotation declaration requires the name of the cache associated with the annotated method: - - In the snippet above, the method findBook is associated with the cache named books. Each time the method is called, the cache - is checked to see whether the invocation has been already executed and does not have to be repeated. While in most cases, only one cache is declared, the annotation allows multiple - names to be specified so that more then one cache are being used. In this case, each of the caches will be checked before executing the method - if at least one cache is hit, - then the associated value will be returned: - All the other caches that do not contain the method will be updated as well even though the cached method was not actually - executed. + In the snippet above, the method findBook is associated with the cache named books. Each time the method is called, the cache + is checked to see whether the invocation has been already executed and does not have to be repeated. While in most cases, only one cache is declared, the annotation allows multiple + names to be specified so that more then one cache are being used. In this case, each of the caches will be checked before executing the method - if at least one cache is hit, + then the associated value will be returned: + All the other caches that do not contain the method will be updated as well even though the cached method was not actually + executed. - -
- Default Key Generation +
+ Default Key Generation - Since caches are essentially key-value stores, each invocation of a cached method needs to be translated into a suitable key for cache access. - Out of the box, the caching abstraction uses a simple KeyGenerator based on the following algorithm: - - If no params are given, return 0. - If only one param is given, return that instance. - If more the one param is given, return a key computed from the hashes of all parameters. - - - This approach works well for objects with natural keys as long as the hashCode() reflects that. If that is not the case then - for distributed or persistent environments, the strategy needs to be changed as the objects hashCode is not preserved. - In fact, depending on the JVM implementation or running conditions, the same hashCode can be reused for different objects, in the same VM instance. + Since caches are essentially key-value stores, each invocation of a cached method needs to be translated into a suitable key for cache access. + Out of the box, the caching abstraction uses a simple KeyGenerator based on the following algorithm: + + If no params are given, return 0. + If only one param is given, return that instance. + If more the one param is given, return a key computed from the hashes of all parameters. + + + This approach works well for objects with natural keys as long as the hashCode() reflects that. If that is not the case then + for distributed or persistent environments, the strategy needs to be changed as the objects hashCode is not preserved. + In fact, depending on the JVM implementation or running conditions, the same hashCode can be reused for different objects, in the same VM instance. - To provide a different default key generator, one needs to implement the org.springframework.cache.KeyGenerator interface. - Once configured, the generator will be used for each declaration that does not specify its own key generation strategy (see below). - -
+ To provide a different default key generator, one needs to implement the org.springframework.cache.KeyGenerator interface. + Once configured, the generator will be used for each declaration that does not specify its own key generation strategy (see below). + +
-
- Custom Key Generation Declaration +
+ Custom Key Generation Declaration - Since caching is generic, it is quite likely the target methods have various signatures that cannot be simply mapped on top of the cache structure. This tends to become - obvious when the target method has multiple arguments out of which only some are suitable for caching (while the rest are used only by the method logic). For example: + Since caching is generic, it is quite likely the target methods have various signatures that cannot be simply mapped on top of the cache structure. This tends to become + obvious when the target method has multiple arguments out of which only some are suitable for caching (while the rest are used only by the method logic). For example: - - At first glance, while the two boolean arguments influence the way the book is found, they are no use for the cache. Further more what if only one of the two - is important while the other is not? + At first glance, while the two boolean arguments influence the way the book is found, they are no use for the cache. Further more what if only one of the two + is important while the other is not? - For such cases, the @Cacheable annotation allows the user to specify how the key is generated through its key attribute. - The developer can use SpEL to pick the arguments of interest (or their nested properties), perform operations or even invoke arbitrary methods without - having to write any code or implement any interface. This is the recommended approach over the default generator since - methods tend to be quite different in signatures as the code base grows; while the default strategy might work for some methods, it rarely does for all methods. + For such cases, the @Cacheable annotation allows the user to specify how the key is generated through its key attribute. + The developer can use SpEL to pick the arguments of interest (or their nested properties), perform operations or even invoke arbitrary methods without + having to write any code or implement any interface. This is the recommended approach over the default generator since + methods tend to be quite different in signatures as the code base grows; while the default strategy might work for some methods, it rarely does for all methods. - - Below are some examples of various SpEL declarations - if you are not familiar with it, do yourself a favour and read : - + + Below are some examples of various SpEL declarations - if you are not familiar with it, do yourself a favour and read : + - + @Cacheable(value="books", key="#isbn" public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @@ -135,465 +139,465 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(value="books", key="T(someType).hash(#isbn)") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) - The snippets above, show how easy it is to select a certain argument, one of its properties or even an arbitrary (static) method. -
+ The snippets above, show how easy it is to select a certain argument, one of its properties or even an arbitrary (static) method. +
-
- Conditional caching +
+ Conditional caching - Sometimes, a method might not be suitable for caching all the time (for example, it might depend on the given arguments). The cache annotations support such functionality - through the conditional parameter which takes a SpEL expression that is evaluated to either true or false. - If true, the method is cached - if not, it behaves as if the method is not cached, that is executed every since time no matter what values are in the cache or what - arguments are used. A quick example - the following method will be cached, only if the argument name has a length shorter then 32: + Sometimes, a method might not be suitable for caching all the time (for example, it might depend on the given arguments). The cache annotations support such functionality + through the conditional parameter which takes a SpEL expression that is evaluated to either true or false. + If true, the method is cached - if not, it behaves as if the method is not cached, that is executed every since time no matter what values are in the cache or what + arguments are used. A quick example - the following method will be cached, only if the argument name has a length shorter then 32: - -
+
-
- Available caching <literal>SpEL</literal> evaluation context +
+ Available caching <literal>SpEL</literal> evaluation context - Each SpEL expression evaluates again a dedicated context. In addition - to the build in parameters, the framework provides dedicated caching related metadata such as the argument names. The next table lists the items made available to the context - so one can use them for key and conditional(see next section) computations: + Each SpEL expression evaluates again a dedicated context. In addition + to the build in parameters, the framework provides dedicated caching related metadata such as the argument names. The next table lists the items made available to the context + so one can use them for key and conditional(see next section) computations: -
- Cache SpEL available metadata - - - - - Name - Location - Description - Example - - - - - methodName - root object - The name of the method being invoked - #root.methodName - - - method - root object - The method being invoked - #root.method.name - - - target - root object - The target object being invoked - #root.target - - - targetClass - root object - The class of the target being invoked - #root.targetClass - - - args - root object - The arguments (as array) used for invoking the target - #root.args[0] - - - caches - root object - Collection of caches against which the current method is executed - #root.caches[0].name - - - argument name - evaluation context - Name of any of the method argument. If for some reason the names are not available (ex: no debug information), - the argument names are also available under the ]]> where - stands for the argument index (starting from 0). - iban or a0 (one can also use p0 or ]]> notation as an alias). - - - -
-
-
+ + Cache SpEL available metadata + + + + + Name + Location + Description + Example + + + + + methodName + root object + The name of the method being invoked + #root.methodName + + + method + root object + The method being invoked + #root.method.name + + + target + root object + The target object being invoked + #root.target + + + targetClass + root object + The class of the target being invoked + #root.targetClass + + + args + root object + The arguments (as array) used for invoking the target + #root.args[0] + + + caches + root object + Collection of caches against which the current method is executed + #root.caches[0].name + + + argument name + evaluation context + Name of any of the method argument. If for some reason the names are not available (ex: no debug information), + the argument names are also available under the ]]> where + stands for the argument index (starting from 0). + iban or a0 (one can also use p0 or ]]> notation as an alias). + + + +
+
+
-
- <literal>@CachePut</literal> annotation +
+ <literal>@CachePut</literal> annotation - For cases where the cache needs to be updated without interfering with the method execution, one can use the @CachePut annotation. That is, the method will always - be executed and its result placed into the cache (according to the @CachePut options). It supports the same options as @Cacheable and should be used - for cache population rather then method flow optimization. + For cases where the cache needs to be updated without interfering with the method execution, one can use the @CachePut annotation. That is, the method will always + be executed and its result placed into the cache (according to the @CachePut options). It supports the same options as @Cacheable and should be used + for cache population rather then method flow optimization. - Note that using @CachePut and @Cacheable annotations on the same method is generally discouraged because they have different behaviors. While the latter - causes the method execution to be skipped by using the cache, the former forces the execution in order to execute a cache update. This leads to unexpected behavior and with the exception of specific - corner-cases (such as annotations having conditions that exclude them from each other), such declarations should be avoided. -
+ Note that using @CachePut and @Cacheable annotations on the same method is generally discouraged because they have different behaviors. While the latter + causes the method execution to be skipped by using the cache, the former forces the execution in order to execute a cache update. This leads to unexpected behavior and with the exception of specific + corner-cases (such as annotations having conditions that exclude them from each other), such declarations should be avoided. +
-
- <literal>@CacheEvict</literal> annotation +
+ <literal>@CacheEvict</literal> annotation - The cache abstraction allows not just population of a cache store but also eviction. This process is useful for removing stale or unused data from the cache. Opposed to - @Cacheable, annotation @CacheEvict demarcates methods that perform cache eviction, that is methods that act as triggers - for removing data from the cache. Just like its sibling, @CacheEvict requires one to specify one (or multiple) caches that are affected by the action, allows a - key or a condition to be specified but in addition, features an extra parameter allEntries which indicates whether a cache-wide eviction needs to be performed - rather then just an entry one (based on the key): + The cache abstraction allows not just population of a cache store but also eviction. This process is useful for removing stale or unused data from the cache. Opposed to + @Cacheable, annotation @CacheEvict demarcates methods that perform cache eviction, that is methods that act as triggers + for removing data from the cache. Just like its sibling, @CacheEvict requires one to specify one (or multiple) caches that are affected by the action, allows a + key or a condition to be specified but in addition, features an extra parameter allEntries which indicates whether a cache-wide eviction needs to be performed + rather then just an entry one (based on the key): - - This option comes in handy when an entire cache region needs to be cleared out - rather then evicting each entry (which would take a long time since it is inefficient), - all the entires are removed in one operation as shown above. Note that the framework will ignore any key specified in this scenario as it does not apply (the entire cache is evicted not just - one entry). + This option comes in handy when an entire cache region needs to be cleared out - rather then evicting each entry (which would take a long time since it is inefficient), + all the entires are removed in one operation as shown above. Note that the framework will ignore any key specified in this scenario as it does not apply (the entire cache is evicted not just + one entry). - One can also indicate whether the eviction should occur after (the default) or before the method executes through the beforeInvocation attribute. - The former provides the same semantics as the rest of the annotations - once the method completes successfully, an action (in this case eviction) on the cache is executed. If the method does not - execute (as it might be cached) or an exception is thrown, the eviction does not occur. The latter (beforeInvocation=true) causes the eviction to occur always, before the method - is invoked - this is useful in cases where the eviction does not need to be tied to the method outcome. + One can also indicate whether the eviction should occur after (the default) or before the method executes through the beforeInvocation attribute. + The former provides the same semantics as the rest of the annotations - once the method completes successfully, an action (in this case eviction) on the cache is executed. If the method does not + execute (as it might be cached) or an exception is thrown, the eviction does not occur. The latter (beforeInvocation=true) causes the eviction to occur always, before the method + is invoked - this is useful in cases where the eviction does not need to be tied to the method outcome. - It is important to note that void methods can be used with @CacheEvict - as the methods act as triggers, the return values are ignored (as they don't interact with - the cache) - this is not the case with @Cacheable which adds/update data into the cache and thus requires a result. -
+ It is important to note that void methods can be used with @CacheEvict - as the methods act as triggers, the return values are ignored (as they don't interact with + the cache) - this is not the case with @Cacheable which adds/update data into the cache and thus requires a result. +
-
- <literal>@Caching</literal> annotation +
+ <literal>@Caching</literal> annotation - There are cases when multiple annotations of the same type, such as @CacheEvict or @CachePut need to be specified, for example because the condition or the key - expression is different between different caches. Unfortunately Java does not support such declarations however there is a workaround - using a enclosing annotation, in this case, - @Caching. @Caching allows multiple nested @Cacheable, @CachePut and @CacheEvict to be used on the same method: + There are cases when multiple annotations of the same type, such as @CacheEvict or @CachePut need to be specified, for example because the condition or the key + expression is different between different caches. Unfortunately Java does not support such declarations however there is a workaround - using a enclosing annotation, in this case, + @Caching. @Caching allows multiple nested @Cacheable, @CachePut and @CacheEvict to be used on the same method: - -
+
-
- Enable caching annotations +
+ Enable caching annotations - It is important to note that even though declaring the cache annotations does not automatically triggers their actions - like many things in Spring, the feature has to be declaratively - enabled (which means if you ever suspect caching is to blame, you can disable it by removing only one configuration line rather then all the annotations in your code). + It is important to note that even though declaring the cache annotations does not automatically triggers their actions - like many things in Spring, the feature has to be declaratively + enabled (which means if you ever suspect caching is to blame, you can disable it by removing only one configuration line rather then all the annotations in your code). - To enable caching annotations add the annotation @EnableCaching to one of your @Configuration classes: + To enable caching annotations add the annotation @EnableCaching to one of your @Configuration classes: - @Configuration + @Configuration @EnableCaching public class AppConfig { } - Alternatively for XML configuration use the cache:annotation-driven element: + Alternatively for XML configuration use the cache:annotation-driven element: - - xmlns:cache="http://www.springframework.org/schema/cache" - http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd]]> - ]]> + + xmlns:cache="http://www.springframework.org/schema/cache" + http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd]]> + ]]> ]]> - Both the cache:annotation-driven element and @EnableCaching annotation allow various options to be specified that influence the way the - caching behavior is added to the application through AOP. The configuration is intentionally similar - with that of @Transactional: - + Both the cache:annotation-driven element and @EnableCaching annotation allow various options to be specified that influence the way the + caching behavior is added to the application through AOP. The configuration is intentionally similar + with that of @Transactional: + - - Cache annotation settings +
+ Cache annotation settings - - - - XML Attribute + + + + XML Attribute - Annotation Attribute + Annotation Attribute - Default + Default - Description - - + Description + + - - - cache-manager - N/A (See CachingConfigurer Javadoc) + + + cache-manager + N/A (See CachingConfigurer Javadoc) - cacheManager + cacheManager - Name of cache manager to use. Only required - if the name of the cache manager is not - cacheManager, as in the example - above. - + Name of cache manager to use. Only required + if the name of the cache manager is not + cacheManager, as in the example + above. + - - mode - mode + + mode + mode - proxy + proxy - The default mode "proxy" processes annotated - beans to be proxied using Spring's AOP framework (following - proxy semantics, as discussed above, applying to method calls - coming in through the proxy only). The alternative mode - "aspectj" instead weaves the affected classes with Spring's - AspectJ caching aspect, modifying the target class byte - code to apply to any kind of method call. AspectJ weaving - requires spring-aspects.jar in the classpath as well as - load-time weaving (or compile-time weaving) enabled. (See - for details on how to set - up load-time weaving.) - + The default mode "proxy" processes annotated + beans to be proxied using Spring's AOP framework (following + proxy semantics, as discussed above, applying to method calls + coming in through the proxy only). The alternative mode + "aspectj" instead weaves the affected classes with Spring's + AspectJ caching aspect, modifying the target class byte + code to apply to any kind of method call. AspectJ weaving + requires spring-aspects.jar in the classpath as well as + load-time weaving (or compile-time weaving) enabled. (See + for details on how to set + up load-time weaving.) + - - proxy-target-class - proxyTargetClass + + proxy-target-class + proxyTargetClass - false + false - Applies to proxy mode only. Controls what type of - caching proxies are created for classes annotated with - the @Cacheable or @CacheEvict annotations. - If the proxy-target-class attribute is set - to true, then class-based proxies are - created. If proxy-target-class is - false or if the attribute is omitted, then - standard JDK interface-based proxies are created. (See for a detailed examination of the - different proxy types.) - + Applies to proxy mode only. Controls what type of + caching proxies are created for classes annotated with + the @Cacheable or @CacheEvict annotations. + If the proxy-target-class attribute is set + to true, then class-based proxies are + created. If proxy-target-class is + false or if the attribute is omitted, then + standard JDK interface-based proxies are created. (See for a detailed examination of the + different proxy types.) + - - order - order + + order + order - Ordered.LOWEST_PRECEDENCE + Ordered.LOWEST_PRECEDENCE - Defines the order of the cache advice that - is applied to beans annotated with - @Cacheable or @CacheEvict. - (For more - information about the rules related to ordering of AOP advice, - see .) No - specified ordering means that the AOP subsystem determines the - order of the advice. - - - -
+ Defines the order of the cache advice that + is applied to beans annotated with + @Cacheable or @CacheEvict. + (For more + information about the rules related to ordering of AOP advice, + see .) No + specified ordering means that the AOP subsystem determines the + order of the advice. + + + + - - <cache:annotation-driven/> only looks for - @Cacheable/@CacheEvict on beans in the same - application context it is defined in. This means that, if you put - <cache:annotation-driven/> in a - WebApplicationContext for a - DispatcherServlet, it only checks for - @Cacheable/@CacheEvict beans in your - controllers, and not your services. See for more information. - + + <cache:annotation-driven/> only looks for + @Cacheable/@CacheEvict on beans in the same + application context it is defined in. This means that, if you put + <cache:annotation-driven/> in a + WebApplicationContext for a + DispatcherServlet, it only checks for + @Cacheable/@CacheEvict beans in your + controllers, and not your services. See for more information. + - - Method visibility and - <interfacename>@Cacheable/@CachePut/@CacheEvict</interfacename> + + Method visibility and + <interfacename>@Cacheable/@CachePut/@CacheEvict</interfacename> - When using proxies, you should apply the - @Cache* annotations only to - methods with public visibility. If you do - annotate protected, private or package-visible methods with these annotations, - no error is raised, but the annotated method does not exhibit the configured - caching settings. Consider the use of AspectJ (see below) if you - need to annotate non-public methods as it changes the bytecode itself. - + When using proxies, you should apply the + @Cache* annotations only to + methods with public visibility. If you do + annotate protected, private or package-visible methods with these annotations, + no error is raised, but the annotated method does not exhibit the configured + caching settings. Consider the use of AspectJ (see below) if you + need to annotate non-public methods as it changes the bytecode itself. + - - Spring recommends that you only annotate concrete classes (and - methods of concrete classes) with the - @Cache* annotation, as opposed - to annotating interfaces. You certainly can place the - @Cache* annotation on an - interface (or an interface method), but this works only as you would - expect it to if you are using interface-based proxies. The fact that - Java annotations are not inherited from interfaces - means that if you are using class-based proxies - (proxy-target-class="true") or the weaving-based - aspect (mode="aspectj"), then the caching - settings are not recognized by the proxying and weaving - infrastructure, and the object will not be wrapped in a - caching proxy, which would be decidedly - bad. - + + Spring recommends that you only annotate concrete classes (and + methods of concrete classes) with the + @Cache* annotation, as opposed + to annotating interfaces. You certainly can place the + @Cache* annotation on an + interface (or an interface method), but this works only as you would + expect it to if you are using interface-based proxies. The fact that + Java annotations are not inherited from interfaces + means that if you are using class-based proxies + (proxy-target-class="true") or the weaving-based + aspect (mode="aspectj"), then the caching + settings are not recognized by the proxying and weaving + infrastructure, and the object will not be wrapped in a + caching proxy, which would be decidedly + bad. + - - In proxy mode (which is the default), only external method calls - coming in through the proxy are intercepted. This means that - self-invocation, in effect, a method within the target object calling - another method of the target object, will not lead to an actual - caching at runtime even if the invoked method is marked with - @Cacheable - considering using the aspectj mode in this case. - -
+ + In proxy mode (which is the default), only external method calls + coming in through the proxy are intercepted. This means that + self-invocation, in effect, a method within the target object calling + another method of the target object, will not lead to an actual + caching at runtime even if the invoked method is marked with + @Cacheable - considering using the aspectj mode in this case. + +
-
- Using custom annotations +
+ Using custom annotations - The caching abstraction allows one to use her own annotations to identify what method trigger cache population or eviction. This is quite handy as a template mechanism as it eliminates - the need to duplicate cache annotation declarations (especially useful if the key or condition are specified) or if the foreign imports (org.springframework) are not allowed - in your code base. Similar to the rest of the stereotype annotations, both @Cacheable and @CacheEvict - can be used as meta-annotations, that is annotations that can annotate other annotations. To wit, let us replace a common @Cacheable declaration with our own, custom - annotation: - + The caching abstraction allows one to use her own annotations to identify what method trigger cache population or eviction. This is quite handy as a template mechanism as it eliminates + the need to duplicate cache annotation declarations (especially useful if the key or condition are specified) or if the foreign imports (org.springframework) are not allowed + in your code base. Similar to the rest of the stereotype annotations, both @Cacheable and @CacheEvict + can be used as meta-annotations, that is annotations that can annotate other annotations. To wit, let us replace a common @Cacheable declaration with our own, custom + annotation: + - - Above, we have defined our own SlowService annotation which itself is annotated with @Cacheable - now we can replace the following code: + Above, we have defined our own SlowService annotation which itself is annotated with @Cacheable - now we can replace the following code: - - with: + with: - - Even though @SlowService is not a Spring annotation, the container automatically picks up its declaration at runtime and understands its meaning. Note that as - mentioned above, the annotation-driven behavior needs to be enabled. -
-
+ Even though @SlowService is not a Spring annotation, the container automatically picks up its declaration at runtime and understands its meaning. Note that as + mentioned above, the annotation-driven behavior needs to be enabled. +
+
-
- Declarative XML-based caching +
+ Declarative XML-based caching - If annotations are not an option (no access to the sources or no external code), one can use XML for declarative caching. So instead of annotating the methods for caching, one specifies - the target method and the caching directives externally (similar to the declarative transaction management advice). The previous example - can be translated into: + If annotations are not an option (no access to the sources or no external code), one can use XML for declarative caching. So instead of annotating the methods for caching, one specifies + the target method and the caching directives externally (similar to the declarative transaction management advice). The previous example + can be translated into: - + - - - - + + + + - + ... // cache manager definition omitted ]]> - + - In the configuration above, the bookService is made cacheable. The caching semantics to apply are encapsulated in the cache:advice definition which - instructs method findBooks to be used for putting data into the cache while method loadBooks for evicting data. Both definitions are working against the - books cache. + In the configuration above, the bookService is made cacheable. The caching semantics to apply are encapsulated in the cache:advice definition which + instructs method findBooks to be used for putting data into the cache while method loadBooks for evicting data. Both definitions are working against the + books cache. - The aop:config definition applies the cache advice to the appropriate points in the program by using the AspectJ pointcut expression (more information is available - in ). In the example above, all methods from the BookService are considered and the cache advice applied to them. + The aop:config definition applies the cache advice to the appropriate points in the program by using the AspectJ pointcut expression (more information is available + in ). In the example above, all methods from the BookService are considered and the cache advice applied to them. - The declarative XML caching supports all of the annotation-based model so moving between the two should be fairly easy - further more both can be used inside the same application. - The XML based approach does not touch the target code however it is inherently more verbose; when dealing with classes with overloaded methods that are targeted for caching, identifying the - proper methods does take an extra effort since the method argument is not a good discriminator - in these cases, the AspectJ pointcut can be used to cherry pick the target - methods and apply the appropriate caching functionality. However through XML, it is easier to apply a package/group/interface-wide caching (again due to the AspectJ pointcut) and to create - template-like definitions (as we did in the example above by defining the target cache through the cache:definitions cache attribute). - -
+ The declarative XML caching supports all of the annotation-based model so moving between the two should be fairly easy - further more both can be used inside the same application. + The XML based approach does not touch the target code however it is inherently more verbose; when dealing with classes with overloaded methods that are targeted for caching, identifying the + proper methods does take an extra effort since the method argument is not a good discriminator - in these cases, the AspectJ pointcut can be used to cherry pick the target + methods and apply the appropriate caching functionality. However through XML, it is easier to apply a package/group/interface-wide caching (again due to the AspectJ pointcut) and to create + template-like definitions (as we did in the example above by defining the target cache through the cache:definitions cache attribute). + +
-
- Configuring the cache storage +
+ Configuring the cache storage - Out of the box, the cache abstraction provides integration with two storages - one on top of the JDK ConcurrentMap and one - for ehcache library. To use them, one needs to simply declare an appropriate CacheManager - an entity that controls and manages - Caches and can be used to retrieve these for storage. + Out of the box, the cache abstraction provides integration with two storages - one on top of the JDK ConcurrentMap and one + for ehcache library. To use them, one needs to simply declare an appropriate CacheManager - an entity that controls and manages + Caches and can be used to retrieve these for storage. -
- JDK <interfacename>ConcurrentMap</interfacename>-based <interfacename>Cache</interfacename> +
+ JDK <interfacename>ConcurrentMap</interfacename>-based <interfacename>Cache</interfacename> - The JDK-based Cache implementation resides under org.springframework.cache.concurrent package. It allows one to use - ConcurrentHashMap as a backing Cache store. + The JDK-based Cache implementation resides under org.springframework.cache.concurrent package. It allows one to use + ConcurrentHashMap as a backing Cache store. - + - - - - - - + + + + + + ]]> - The snippet above uses the SimpleCacheManager to create a CacheManager for the two, nested Concurrent - Cache implementations named default and books. - Note that the names are configured directly for each cache. + The snippet above uses the SimpleCacheManager to create a CacheManager for the two, nested Concurrent + Cache implementations named default and books. + Note that the names are configured directly for each cache. - As the cache is created by the application, it is bound to its lifecycle, making it suitable for basic use cases, tests or simple applications. The cache scales well and is very fast - but it does not provide any management or persistence capabilities nor eviction contracts. -
+ As the cache is created by the application, it is bound to its lifecycle, making it suitable for basic use cases, tests or simple applications. The cache scales well and is very fast + but it does not provide any management or persistence capabilities nor eviction contracts. +
-
- Ehcache-based <interfacename>Cache</interfacename> +
+ Ehcache-based <interfacename>Cache</interfacename> - The Ehcache implementation is located under org.springframework.cache.ehcache package. Again, to use it, one simply needs to declare the appropriate - CacheManager: + The Ehcache implementation is located under org.springframework.cache.ehcache package. Again, to use it, one simply needs to declare the appropriate + CacheManager: - + ]]> - This setup bootstraps ehcache library inside Spring IoC (through bean ehcache) which is then wired into the dedicated CacheManager - implementation. Note the entire ehcache-specific configuration is read from the resource ehcache.xml. -
+ This setup bootstraps ehcache library inside Spring IoC (through bean ehcache) which is then wired into the dedicated CacheManager + implementation. Note the entire ehcache-specific configuration is read from the resource ehcache.xml. +
-
- Dealing with caches without a backing store +
+ Dealing with caches without a backing store - Sometimes when switching environments or doing testing, one might have cache declarations without an actual backing cache configured. As this is an invalid configuration, at runtime an - exception will be through since the caching infrastructure is unable to find a suitable store. In situations like this, rather then removing the cache declarations (which can prove tedious), - one can wire in a simple, dummy cache that performs no caching - that is, forces the cached methods to be executed every time: + Sometimes when switching environments or doing testing, one might have cache declarations without an actual backing cache configured. As this is an invalid configuration, at runtime an + exception will be through since the caching infrastructure is unable to find a suitable store. In situations like this, rather then removing the cache declarations (which can prove tedious), + one can wire in a simple, dummy cache that performs no caching - that is, forces the cached methods to be executed every time: - - - - - - + + + + + + ]]> - The CompositeCacheManager above chains multiple CacheManagers and additionally, through the addNoOpManager flag, adds a - no op cache that for all the definitions not handled by the configured cache managers. That is, every cache definition not found in either jdkCache - or gemfireCache (configured above) will be handled by the no op cache, which will not store any information causing the target method to be executed every time. - -
-
+ The CompositeCacheManager above chains multiple CacheManagers and additionally, through the addNoOpManager flag, adds a + no op cache that for all the definitions not handled by the configured cache managers. That is, every cache definition not found in either jdkCache + or gemfireCache (configured above) will be handled by the no op cache, which will not store any information causing the target method to be executed every time. + +
+
-
- Plugging-in different back-end caches +
+ Plugging-in different back-end caches - Clearly there are plenty of caching products out there that can be used as a backing store. To plug them in, one needs to provide a CacheManager and - Cache implementation since unfortunately there is no available standard that we can use instead. This may sound harder then it is since in practice, - the classes tend to be simple adapters that map the caching abstraction framework on top of the storage API as the ehcache classes can show. - Most CacheManager classes can use the classes in org.springframework.cache.support package, such as AbstractCacheManager - which takes care of the boiler-plate code leaving only the actual mapping to be completed. We hope that in time, the libraries that provide integration with Spring - can fill in this small configuration gap. -
+ Clearly there are plenty of caching products out there that can be used as a backing store. To plug them in, one needs to provide a CacheManager and + Cache implementation since unfortunately there is no available standard that we can use instead. This may sound harder then it is since in practice, + the classes tend to be simple adapters that map the caching abstraction framework on top of the storage API as the ehcache classes can show. + Most CacheManager classes can use the classes in org.springframework.cache.support package, such as AbstractCacheManager + which takes care of the boiler-plate code leaving only the actual mapping to be completed. We hope that in time, the libraries that provide integration with Spring + can fill in this small configuration gap. +
-
- How can I set the TTL/TTI/Eviction policy/XXX feature? +
+ How can I set the TTL/TTI/Eviction policy/XXX feature? - Directly through your cache provider. The cache abstraction is... well, an abstraction not a cache implementation. The solution you are using might support various data policies and different - topologies which other solutions do not (take for example the JDK ConcurrentHashMap) - exposing that in the cache abstraction would be useless simply because there would - no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API. - -
+ Directly through your cache provider. The cache abstraction is... well, an abstraction not a cache implementation. The solution you are using might support various data policies and different + topologies which other solutions do not (take for example the JDK ConcurrentHashMap) - exposing that in the cache abstraction would be useless simply because there would + no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API. + +
diff --git a/src/reference/docbook/cci.xml b/src/reference/docbook/cci.xml index 0597c48734..e5fc3bb82f 100644 --- a/src/reference/docbook/cci.xml +++ b/src/reference/docbook/cci.xml @@ -1,11 +1,15 @@ - + 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"> JCA CCI -
+
Introduction Java EE provides a specification to standardize access to enterprise @@ -45,10 +49,10 @@
-
+
Configuring CCI -
+
Connector configuration The base resource to use JCA CCI is the @@ -90,7 +94,7 @@
-
+
<interfacename>ConnectionFactory</interfacename> configuration in Spring @@ -133,7 +137,7 @@
-
+
Configuring CCI connections JCA CCI allow the developer to configure the connections to the @@ -192,7 +196,7 @@ </bean>
-
+
Using a single CCI connection If you want to use a single CCI connection, Spring provides a @@ -232,10 +236,10 @@
-
+
Using Spring's CCI access support -
+
Record conversion One of the aims of the JCA CCI support is to provide convenient @@ -299,7 +303,7 @@ }
-
+
The <classname>CciTemplate</classname> The CciTemplate is the central class of the @@ -408,7 +412,7 @@ }
-
+
DAO support Spring's CCI support provides a abstract class for DAOs, @@ -433,7 +437,7 @@ }
-
+
Automatic output record generation If the connector used only supports the @@ -473,13 +477,13 @@
-
+
Summary The following table summarizes the mechanisms of the CciTemplate class and the corresponding methods called on the CCI Interaction - interface: + interface:
Usage of <interfacename>Interaction</interfacename> execute methods @@ -601,7 +605,7 @@
-
+
Using a CCI <interfacename>Connection</interfacename> and <interfacename>Interaction</interfacename> directly @@ -646,7 +650,7 @@
-
+
Example for <classname>CciTemplate</classname> usage In this section, the usage of the @@ -700,7 +704,7 @@ interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);// do something... } }); @@ -771,7 +775,7 @@ interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
-
+
Modeling CCI access as operation objects The org.springframework.jca.cci.object package @@ -788,7 +792,7 @@ interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);RecordExtractor interfaces, reusing the machinery of Spring's core CCI support. -
+
<classname>MappingRecordOperation</classname> MappingRecordOperation essentially performs @@ -847,7 +851,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti ...
-
+
<classname>MappingCommAreaOperation</classname> Some connectors use records based on a COMMAREA which represents @@ -872,7 +876,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti }
-
+
Automatic output record generation As every MappingRecordOperation subclass is @@ -883,13 +887,13 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti information, see .
-
+
Summary The operation object approach uses records in the same manner as the CciTemplate class. - +
Usage of Interaction execute methods @@ -931,7 +935,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
-
+
Example for <classname>MappingRecordOperation</classname> usage @@ -1045,7 +1049,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti </bean>
-
+
Example for <classname>MappingCommAreaOperation</classname> usage @@ -1130,7 +1134,7 @@ MyMappingRecordOperation eisOperation = new MyMappingRecordOperation(getConnecti
-
+
Transactions JCA specifies several levels of transaction support for resource diff --git a/src/reference/docbook/classic-aop-spring.xml b/src/reference/docbook/classic-aop-spring.xml index 7954ab3bf4..68cb0d62db 100644 --- a/src/reference/docbook/classic-aop-spring.xml +++ b/src/reference/docbook/classic-aop-spring.xml @@ -1,24 +1,28 @@ - + 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"> Classic Spring AOP Usage - In this appendix we discuss - the lower-level Spring AOP APIs and the AOP support used in Spring 1.2 applications. - For new applications, we recommend the use of the Spring 2.0 AOP support - described in the AOP chapter, but when working with existing applications, - or when reading books and articles, you may come across Spring 1.2 style examples. - Spring 2.0 is fully backwards compatible with Spring 1.2 and everything described - in this appendix is fully supported in Spring 2.0. + In this appendix we discuss + the lower-level Spring AOP APIs and the AOP support used in Spring 1.2 applications. + For new applications, we recommend the use of the Spring 2.0 AOP support + described in the AOP chapter, but when working with existing applications, + or when reading books and articles, you may come across Spring 1.2 style examples. + Spring 2.0 is fully backwards compatible with Spring 1.2 and everything described + in this appendix is fully supported in Spring 2.0. -
+
Pointcut API in Spring Let's look at how Spring handles the crucial pointcut concept. -
+
Concepts Spring's pointcut model enables pointcut reuse independent of @@ -79,41 +83,41 @@ isRuntime() method returns false. In this case, the 3-argument matches method will never be invoked. - - If possible, try to make pointcuts static, allowing the AOP - framework to cache the results of pointcut evaluation when an AOP proxy - is created. - + + If possible, try to make pointcuts static, allowing the AOP + framework to cache the results of pointcut evaluation when an AOP proxy + is created. +
-
+
Operations on pointcuts Spring supports operations on pointcuts: notably, union and intersection. - - - Union means the methods that either pointcut matches. - - - Intersection means the methods that both pointcuts match. - - - Union is usually more useful. - - - Pointcuts can be composed using the static methods in the - org.springframework.aop.support.Pointcuts class, or - using the ComposablePointcut class in the same - package. However, using AspectJ pointcut expressions is usually a - simpler approach. - - + + + Union means the methods that either pointcut matches. + + + Intersection means the methods that both pointcuts match. + + + Union is usually more useful. + + + Pointcuts can be composed using the static methods in the + org.springframework.aop.support.Pointcuts class, or + using the ComposablePointcut class in the same + package. However, using AspectJ pointcut expressions is usually a + simpler approach. + +
-
+
AspectJ expression pointcuts Since 2.0, the most important type of pointcut used by Spring is @@ -126,14 +130,14 @@
-
+
Convenience pointcut implementations Spring provides several convenient pointcut implementations. Some can be used out of the box; others are intended to be subclassed in application-specific pointcuts. -
+
Static pointcuts Static pointcuts are based on method and target class, and @@ -146,7 +150,7 @@ Let's consider some static pointcut implementations included with Spring. -
+
Regular expression pointcuts One obvious way to specify static pointcuts is regular @@ -166,7 +170,7 @@ The usage is shown below: - <bean id="settersAndAbsquatulatePointcut" + <bean id="settersAndAbsquatulatePointcut" class="org.springframework.aop.support.Perl5RegexpMethodPointcut"> <property name="patterns"> <list> @@ -185,7 +189,7 @@ as the one bean encapsulates both pointcut and advice, as shown below: - <bean id="settersAndAbsquatulateAdvisor" + <bean id="settersAndAbsquatulateAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="beanNameOfAopAllianceInterceptor"/> @@ -202,7 +206,7 @@ with any Advice type.
-
+
Attribute-driven pointcuts An important type of static pointcut is a @@ -211,7 +215,7 @@
-
+
Dynamic pointcuts Dynamic pointcuts are costlier to evaluate than static @@ -223,13 +227,13 @@ The main example is the control flow pointcut. -
+
Control flow pointcuts Spring control flow pointcuts are conceptually similar to AspectJ cflow pointcuts, although less powerful. (There is currently no way to specify that a pointcut - executes below a join point matched by another pointcut.) + executes below a join point matched by another pointcut.) A control flow pointcut matches the current call stack. For example, it might fire if the join point was invoked by a method in the com.mycompany.web @@ -245,7 +249,7 @@
-
+
Pointcut superclasses Spring provides useful pointcut superclasses to help you to @@ -267,7 +271,7 @@ RC2 and above.
-
+
Custom pointcuts Because pointcuts in Spring AOP are Java classes, rather than @@ -277,22 +281,22 @@ language is recommended if possible. - Later versions of Spring may offer support for "semantic - pointcuts" as offered by JAC: for example, "all methods that change - instance variables in the target object." - + Later versions of Spring may offer support for "semantic + pointcuts" as offered by JAC: for example, "all methods that change + instance variables in the target object." +
-
+
Advice API in Spring Let's now look at how Spring AOP handles advice. -
+
Advice lifecycles - Each advice is a Spring bean. An advice instance can be shared across all + Each advice is a Spring bean. An advice instance can be shared across all advised objects, or unique to each advised object. This corresponds to per-class or per-instance @@ -311,14 +315,14 @@ the same AOP proxy.
-
+
Advice types in Spring 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. -
+
Interception around advice The most fundamental advice type in Spring is @@ -329,7 +333,7 @@ around advice should implement the following interface: public interface MethodInterceptor extends Interceptor { - + Object invoke(MethodInvocation invocation) throws Throwable; } @@ -371,7 +375,7 @@ pointcut interfaces.
-
+
Before advice A simpler advice type is a before @@ -414,15 +418,15 @@ ++count; } - public int getCount() { - return count; + public int getCount() { + return count; } } Before advice can be used with any pointcut.
-
+
Throws advice Throws advice is invoked after @@ -441,7 +445,7 @@ classes are examples of throws advice. The advice below is invoked if a RemoteException - is thrown (including subclasses): + is thrown (including subclasses): Do not throw an undeclared checked exception that is incompatible with the target method's signature! - Throws advice can be used with any pointcut. + Throws advice can be used with any pointcut.
-
+
After Returning advice An after returning advice in Spring must implement the @@ -499,7 +503,7 @@ 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; } @@ -528,10 +532,10 @@ exception, this will be thrown up the interceptor chain instead of the return value. - After returning advice can be used with any pointcut. + After returning advice can be used with any pointcut.
-
+
Introduction advice Spring treats introduction advice as a special kind of interception advice. @@ -550,53 +554,47 @@ interface, the introduction interceptor is responsible for handling the method call - it cannot invoke proceed(). - + 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 IntroductionAdvisor, which has the following methods: - + 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(); } - + There is no MethodMatcher, and hence no Pointcut, associated with introduction advice. Only class filtering is logical. - + The getInterfaces() method returns the interfaces introduced by this advisor. - The - - validateInterfaces() - - method is used internally to see whether or not the introduced interfaces can be implemented by the configured - - IntroductionInterceptor - - . + The validateInterfaces() method is used internally to + see whether or not the introduced interfaces can be implemented by the configured + IntroductionInterceptor. 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: - + public interface Lockable { @@ -606,7 +604,7 @@ public interface IntroductionInfo { } - + This illustrates a mixin. We want to be able to cast advised objects to Lockable, whatever their @@ -616,7 +614,7 @@ public interface IntroductionInfo { provides the ability to make objects immutable, without them having any knowledge of it: a good example of AOP. - + Firstly, we'll need an IntroductionInterceptor that does the heavy @@ -627,7 +625,7 @@ public interface IntroductionInfo { DelegatingIntroductionInterceptor is best for most cases. - + The DelegatingIntroductionInterceptor is designed to delegate an introduction to an actual implementation of @@ -651,7 +649,7 @@ public interface IntroductionInfo { will conceal any implementation of the same interface by the target. - + Thus LockMixin subclasses DelegatingIntroductionInterceptor and implements @@ -659,16 +657,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. - + Note the use of the locked instance variable. This effectively adds additional state to that held in the target object. - + - public class LockMixin extends DelegatingIntroductionInterceptor + public class LockMixin extends DelegatingIntroductionInterceptor implements Lockable { private boolean locked; @@ -694,7 +692,7 @@ public interface IntroductionInfo { } - + Often it isn't necessary to override the invoke() method: the @@ -704,7 +702,7 @@ public interface IntroductionInfo { sufficient. In the present case, we need to add a check: no setter method can be invoked if in locked mode. - + The introduction advisor required is simple. All it needs to do is hold a distinct LockMixin instance, and specify @@ -715,7 +713,7 @@ public interface IntroductionInfo { LockMixin, so we simply create it using new. - + public class LockMixinAdvisor extends DefaultIntroductionAdvisor { @@ -726,7 +724,7 @@ public interface IntroductionInfo { } - + We can apply this advisor very simply: it requires no configuration. (However, it is necessary: It's @@ -737,7 +735,7 @@ public interface IntroductionInfo { hence LockMixin, for each advised object. The advisor comprises part of the advised object's state. - + We can apply this advisor programmatically, using the Advised.addAdvisor() method, or (the recommended @@ -745,12 +743,12 @@ public interface IntroductionInfo { choices discussed below, including "auto proxy creators," correctly handle introductions and stateful mixins. - +
-
+
Advisor API in Spring In Spring, an Advisor is an aspect that contains just a single advice @@ -769,7 +767,7 @@ public interface IntroductionInfo { automatically create the necessary interceptor chain.
-
+
Using the ProxyFactoryBean to create AOP proxies If you're using the Spring IoC container (an ApplicationContext or @@ -777,18 +775,18 @@ public interface IntroductionInfo { to use one of Spring's AOP FactoryBeans. (Remember that a factory bean introduces a layer of indirection, enabling it to create objects of a different type.) - - - The Spring 2.0 AOP support also uses factory beans under the covers. - - + + + The Spring 2.0 AOP support also uses factory beans under the covers. + + The basic way to create an AOP proxy in Spring is to use the org.springframework.aop.framework.ProxyFactoryBean. This gives complete control over the pointcuts and advice that will apply, and their ordering. However, there are simpler options that are preferable if you don't need such control. -
+
Basics The ProxyFactoryBean, like other Spring @@ -811,202 +809,202 @@ public interface IntroductionInfo { pluggability provided by Dependency Injection.
-
+
JavaBean properties - In common with most FactoryBean implementations - provided with Spring, the ProxyFactoryBean class is - itself a JavaBean. Its properties are used to: - + In common with most FactoryBean implementations + provided with Spring, the ProxyFactoryBean class is + itself a JavaBean. Its properties are used to: + Specify the target you want to proxy. Specify whether to use CGLIB (see below and also - ). + ). - Some key properties are inherited from - org.springframework.aop.framework.ProxyConfig (the - superclass for all AOP proxy factories in Spring). These key properties include: + Some key properties are inherited from + org.springframework.aop.framework.ProxyConfig (the + superclass for all AOP proxy factories in Spring). These key properties include: - proxyTargetClass: true if the - target class is to be proxied, rather than the target class' interfaces. - If this property value is set to true, then CGLIB proxies - will be created (but see also below ). - + proxyTargetClass: true if the + target class is to be proxied, rather than the target class' interfaces. + If this property value is set to true, then CGLIB proxies + will be created (but see also below ). + - optimize: controls whether or not aggressive - optimizations are applied to proxies created via CGLIB. - One should not blithely use this setting unless one fully understands - how the relevant AOP proxy handles optimization. This is currently used only - for CGLIB proxies; it has no effect with JDK dynamic proxies. + optimize: controls whether or not aggressive + optimizations are applied to proxies created via CGLIB. + One should not blithely use this setting unless one fully understands + how the relevant AOP proxy handles optimization. This is currently used only + for CGLIB proxies; it has no effect with JDK dynamic proxies. frozen: if a proxy configuration is frozen, - then changes to the configuration are no longer allowed. This is useful both as - a slight optimization and for those cases when you don't want callers to be able - to manipulate the proxy (via the Advised interface) - after the proxy has been created. The default value of this property is - false, so changes such as adding additional advice are allowed. + then changes to the configuration are no longer allowed. This is useful both as + a slight optimization and for those cases when you don't want callers to be able + to manipulate the proxy (via the Advised interface) + after the proxy has been created. The default value of this property is + false, so changes such as adding additional advice are allowed. - exposeProxy: determines whether or not the current - proxy should be exposed in a ThreadLocal so that - it can be accessed by the target. If a target needs to obtain - the proxy and the exposeProxy property is set to - true, the target can use the - AopContext.currentProxy() method. + exposeProxy: determines whether or not the current + proxy should be exposed in a ThreadLocal so that + it can be accessed by the target. If a target needs to obtain + the proxy and the exposeProxy property is set to + true, the target can use the + AopContext.currentProxy() method. - aopProxyFactory: the implementation of - AopProxyFactory to use. Offers a way of - customizing whether to use dynamic proxies, CGLIB or any other proxy - strategy. The default implementation will choose dynamic proxies or - CGLIB appropriately. There should be no need to use this property; - it is intended to allow the addition of new proxy types in Spring 1.1. + aopProxyFactory: the implementation of + AopProxyFactory to use. Offers a way of + customizing whether to use dynamic proxies, CGLIB or any other proxy + strategy. The default implementation will choose dynamic proxies or + CGLIB appropriately. There should be no need to use this property; + it is intended to allow the addition of new proxy types in Spring 1.1. - Other properties specific to ProxyFactoryBean include: - + Other properties specific to ProxyFactoryBean include: + - proxyInterfaces: array of String interface - names. If this isn't supplied, a CGLIB proxy for the target class - will be used (but see also below ). + proxyInterfaces: array of String interface + names. If this isn't supplied, a CGLIB proxy for the target class + will be used (but see also below ). - interceptorNames: String array of - Advisor, interceptor or other advice - names to apply. Ordering is significant, on a first come-first served - basis. That is to say that the first interceptor in the list - will be the first to be able to intercept the invocation. + interceptorNames: String array of + Advisor, interceptor or other advice + names to apply. Ordering is significant, on a first come-first served + basis. That is to say that the first interceptor in the list + will be the first to be able to intercept the invocation. - The names are bean names in the current factory, including - bean names from ancestor factories. You can't mention bean - references here since doing so would result in the - ProxyFactoryBean ignoring the singleton - setting of the advice. + The names are bean names in the current factory, including + bean names from ancestor factories. You can't mention bean + references here since doing so would result in the + ProxyFactoryBean ignoring the singleton + setting of the advice. - You can append an interceptor name with an asterisk - (*). This will result in the application of all - advisor beans with names starting with the part before the asterisk - to be applied. An example of using this feature can be found in - . + You can append an interceptor name with an asterisk + (*). This will result in the application of all + advisor beans with names starting with the part before the asterisk + to be applied. An example of using this feature can be found in + . - singleton: whether or not the factory should return a single - object, no matter how often the getObject() - method is called. Several FactoryBean - implementations offer such a method. The default value is - true. If you want to use stateful advice - - for example, for stateful mixins - use prototype advices along - with a singleton value of false. + singleton: whether or not the factory should return a single + object, no matter how often the getObject() + method is called. Several FactoryBean + implementations offer such a method. The default value is + true. If you want to use stateful advice - + for example, for stateful mixins - use prototype advices along + with a singleton value of false.
- -
- JDK- and CGLIB-based proxies + +
+ JDK- and CGLIB-based proxies - This section serves as the definitive documentation on how the - ProxyFactoryBean chooses to create one of - either a JDK- and CGLIB-based proxy for a particular target object - (that is to be proxied). + This section serves as the definitive documentation on how the + ProxyFactoryBean chooses to create one of + either a JDK- and CGLIB-based proxy for a particular target object + (that is to be proxied). - - The behavior of the ProxyFactoryBean with regard - to creating JDK- or CGLIB-based proxies changed between versions 1.2.x and - 2.0 of Spring. The ProxyFactoryBean now - exhibits similar semantics with regard to auto-detecting interfaces - as those of the TransactionProxyFactoryBean class. - + + The behavior of the ProxyFactoryBean with regard + to creating JDK- or CGLIB-based proxies changed between versions 1.2.x and + 2.0 of Spring. The ProxyFactoryBean now + exhibits similar semantics with regard to auto-detecting interfaces + as those of the TransactionProxyFactoryBean class. + - - If the class of a target object that is to be proxied (hereafter simply - referred to as the target class) doesn't implement any interfaces, then - a CGLIB-based proxy will be created. This is the easiest scenario, because - JDK proxies are interface based, and no interfaces means JDK proxying - isn't even possible. One simply plugs in the target bean, and specifies the - list of interceptors via the interceptorNames property. - Note that a CGLIB-based proxy will be created even if the - proxyTargetClass property of the - ProxyFactoryBean has been set to false. - (Obviously this makes no sense, and is best removed from the bean - definition because it is at best redundant, and at worst confusing.) - - - If the target class implements one (or more) interfaces, then the type of - proxy that is created depends on the configuration of the - ProxyFactoryBean. - - - If the proxyTargetClass property of the - ProxyFactoryBean has been set to true, - then a CGLIB-based proxy will be created. This makes sense, and is in - keeping with the principle of least surprise. Even if the - proxyInterfaces property of the - ProxyFactoryBean has been set to one or more - fully qualified interface names, the fact that the - proxyTargetClass property is set to - true will cause - CGLIB-based proxying to be in effect. - - - If the proxyInterfaces property of the - ProxyFactoryBean has been set to one or more - fully qualified interface names, then a JDK-based proxy will be created. - The created proxy will implement all of the interfaces that were specified - in the proxyInterfaces property; if the target class - happens to implement a whole lot more interfaces than those specified in - the proxyInterfaces property, that is all well and - good but those additional interfaces will not be implemented by the - returned proxy. - - - If the proxyInterfaces property of the - ProxyFactoryBean has not been - set, but the target class does implement one (or more) - interfaces, then the ProxyFactoryBean will auto-detect - the fact that the target class does actually implement at least one interface, - and a JDK-based proxy will be created. The interfaces that are actually - proxied will be all of the interfaces that the target - class implements; in effect, this is the same as simply supplying a list - of each and every interface that the target class implements to the - proxyInterfaces property. However, it is significantly less - work, and less prone to typos. - + + If the class of a target object that is to be proxied (hereafter simply + referred to as the target class) doesn't implement any interfaces, then + a CGLIB-based proxy will be created. This is the easiest scenario, because + JDK proxies are interface based, and no interfaces means JDK proxying + isn't even possible. One simply plugs in the target bean, and specifies the + list of interceptors via the interceptorNames property. + Note that a CGLIB-based proxy will be created even if the + proxyTargetClass property of the + ProxyFactoryBean has been set to false. + (Obviously this makes no sense, and is best removed from the bean + definition because it is at best redundant, and at worst confusing.) + + + If the target class implements one (or more) interfaces, then the type of + proxy that is created depends on the configuration of the + ProxyFactoryBean. + + + If the proxyTargetClass property of the + ProxyFactoryBean has been set to true, + then a CGLIB-based proxy will be created. This makes sense, and is in + keeping with the principle of least surprise. Even if the + proxyInterfaces property of the + ProxyFactoryBean has been set to one or more + fully qualified interface names, the fact that the + proxyTargetClass property is set to + true will cause + CGLIB-based proxying to be in effect. + + + If the proxyInterfaces property of the + ProxyFactoryBean has been set to one or more + fully qualified interface names, then a JDK-based proxy will be created. + The created proxy will implement all of the interfaces that were specified + in the proxyInterfaces property; if the target class + happens to implement a whole lot more interfaces than those specified in + the proxyInterfaces property, that is all well and + good but those additional interfaces will not be implemented by the + returned proxy. + + + If the proxyInterfaces property of the + ProxyFactoryBean has not been + set, but the target class does implement one (or more) + interfaces, then the ProxyFactoryBean will auto-detect + the fact that the target class does actually implement at least one interface, + and a JDK-based proxy will be created. The interfaces that are actually + proxied will be all of the interfaces that the target + class implements; in effect, this is the same as simply supplying a list + of each and every interface that the target class implements to the + proxyInterfaces property. However, it is significantly less + work, and less prone to typos. +
-
+
Proxying interfaces - Let's look at a simple example of ProxyFactoryBean - in action. This example involves: + Let's look at a simple example of ProxyFactoryBean + in action. This example involves: @@ -1038,7 +1036,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</value></property> @@ -1057,16 +1055,16 @@ public interface IntroductionInfo { throws advice objects can be used. The ordering of advisors is significant. - - You might be wondering why the list doesn't hold bean - references. The reason for this is that if the ProxyFactoryBean's - singleton property is set to false, it must be able to return - independent proxy instances. If any of the advisors is itself a - prototype, an independent instance would need to be returned, so it's - necessary to be able to obtain an instance of the prototype from the - factory; holding a reference isn't sufficient. - - + + You might be wondering why the list doesn't hold bean + references. The reason for this is that if the ProxyFactoryBean's + singleton property is set to false, it must be able to return + independent proxy instances. If any of the advisors is itself a + prototype, an independent instance would need to be returned, so it's + necessary to be able to obtain an instance of the prototype from the + factory; holding a reference isn't sufficient. + + The "person" bean definition above can be used in place of a Person implementation, as follows: @@ -1125,7 +1123,7 @@ public interface IntroductionInfo { example, in certain test scenarios.
-
+
Proxying classes What if you need to proxy a class, rather than one or more @@ -1176,7 +1174,7 @@ public interface IntroductionInfo { decisive consideration in this case.
-
+
Using 'global' advisors By appending an asterisk to an interceptor name, all advisors with @@ -1198,7 +1196,7 @@ public interface IntroductionInfo {
-
+
Concise proxy definitions Especially when defining transactional proxies, you may end up with @@ -1261,7 +1259,7 @@ public interface IntroductionInfo { it.
-
+
Creating AOP proxies programmatically with the ProxyFactory It's easy to create AOP proxies programmatically using Spring. This @@ -1287,18 +1285,18 @@ MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy(); There are also convenience methods on ProxyFactory (inherited from - AdvisedSupport) which allow you to add other advice types - such as before and throws advice. AdvisedSupport is the superclass of both + AdvisedSupport) which allow you to add other advice types + such as before and throws advice. AdvisedSupport is the superclass of both ProxyFactory and ProxyFactoryBean. - - Integrating AOP proxy creation with the IoC framework is best - practice in most applications. We recommend that you externalize - configuration from Java code with AOP, as in general. - + + Integrating AOP proxy creation with the IoC framework is best + practice in most applications. We recommend that you externalize + configuration from Java code with AOP, as in general. +
-
+
Manipulating advised objects However you create AOP proxies, you can manipulate them using the @@ -1310,7 +1308,7 @@ MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy(); - - It's questionable whether it's advisable (no pun intended) to - modify advice on a business object in production, although there are no - doubt legitimate usage cases. However, it can be very useful in - development: for example, in tests. I have sometimes found it very useful - to be able to add test code in the form of an interceptor or other advice, - getting inside a method invocation I want to test. (For example, the - advice can get inside a transaction created for that method: for example, - to run SQL to check that a database was correctly updated, before marking - the transaction for roll back.) - - + + It's questionable whether it's advisable (no pun intended) to + modify advice on a business object in production, although there are no + doubt legitimate usage cases. However, it can be very useful in + development: for example, in tests. I have sometimes found it very useful + to be able to add test code in the form of an interceptor or other advice, + getting inside a method invocation I want to test. (For example, the + advice can get inside a transaction created for that method: for example, + to run SQL to check that a database was correctly updated, before marking + the transaction for roll back.) + + Depending on how you created the proxy, you can usually set a frozen flag, in which case the Advised isFrozen() method will @@ -1392,7 +1390,7 @@ assertEquals("Added two advisors", advice modification is known not to be required.
-
+
Using the "autoproxy" facility So far we've considered explicit creation of AOP proxies using a @@ -1423,13 +1421,13 @@ assertEquals("Added two advisors", -
+
Autoproxy bean definitions The org.springframework.aop.framework.autoproxy package provides the following standard autoproxy creators. -
+
BeanNameAutoProxyCreator The BeanNameAutoProxyCreator class is a @@ -1465,7 +1463,7 @@ assertEquals("Added two advisors", differently to different beans.
-
+
DefaultAdvisorAutoProxyCreator A more general and extremely powerful auto proxy creator is @@ -1544,7 +1542,7 @@ assertEquals("Added two advisors", configurable order value; the default setting is unordered.
-
+
AbstractAdvisorAutoProxyCreator This is the superclass of DefaultAdvisorAutoProxyCreator. You @@ -1555,7 +1553,7 @@ assertEquals("Added two advisors",
-
+
Using metadata-driven auto-proxying A particularly important type of autoproxying is driven by @@ -1645,17 +1643,17 @@ assertEquals("Added two advisors", be specific to the application's transaction requirements (typically JTA, as in this example, or Hibernate, JDO or JDBC): - <bean id="transactionManager" + <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/> - - If you require only declarative transaction management, using - these generic XML definitions will result in Spring automatically - proxying all classes or methods with transaction attributes. You won't - need to work directly with AOP, and the programming model is similar to - that of .NET ServicedComponents. - - + + If you require only declarative transaction management, using + these generic XML definitions will result in Spring automatically + proxying all classes or methods with transaction attributes. You won't + need to work directly with AOP, and the programming model is similar to + that of .NET ServicedComponents. + + This mechanism is extensible. It's possible to do autoproxying based on custom attributes. You need to: @@ -1703,7 +1701,7 @@ assertEquals("Added two advisors",
-
+
Using TargetSources Spring offers the concept of a TargetSource, @@ -1726,13 +1724,13 @@ assertEquals("Added two advisors", Let's look at the standard target sources provided with Spring, and how you can use them. - - When using a custom target source, your target will usually need - to be a prototype rather than a singleton bean definition. This allows - Spring to create a new target instance when required. - - -
+ + When using a custom target source, your target will usually need + to be a prototype rather than a singleton bean definition. This allows + Spring to create a new target instance when required. + + +
Hot swappable target sources The @@ -1746,7 +1744,7 @@ assertEquals("Added two advisors", You can change the target via the swap() method on HotSwappableTargetSource as follows: - HotSwappableTargetSource swapper = + HotSwappableTargetSource swapper = (HotSwappableTargetSource) beanFactory.getBean("swapper"); Object oldTarget = swapper.swap(newTarget); @@ -1773,7 +1771,7 @@ Object oldTarget = swapper.swap(newTarget); with arbitrary advice.
-
+
Pooling target sources Using a pooling target source provides a similar programming model @@ -1794,7 +1792,7 @@ Object oldTarget = swapper.swap(newTarget); Sample configuration is shown below: - <bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject" + <bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject" scope="prototype"> ... properties omitted </bean> @@ -1846,18 +1844,18 @@ Object oldTarget = swapper.swap(newTarget); - - Pooling stateless service objects is not usually necessary. We - don't believe it should be the default choice, as most stateless objects - are naturally thread safe, and instance pooling is problematic if - resources are cached. - - + + Pooling stateless service objects is not usually necessary. We + don't believe it should be the default choice, as most stateless objects + are naturally thread safe, and instance pooling is problematic if + resources are cached. + + Simpler pooling is available using autoproxying. It's possible to set the TargetSources used by any autoproxy creator.
-
+
Prototype target sources Setting up a "prototype" target source is similar to a pooling @@ -1881,7 +1879,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());]]> must be a prototype bean definition.
-
+
<classname>ThreadLocal</classname> target sources ThreadLocal target sources are useful if you need an object to be @@ -1895,24 +1893,24 @@ System.out.println("Max pool size is " + conf.getMaxSize());]]> ]]> - - ThreadLocals come with serious issues (potentially - resulting in memory leaks) when incorrectly using them in a - multi-threaded and multi-classloader environments. One should always - consider wrapping a threadlocal in some other class and never directly - use the ThreadLocal itself (except of course in the wrapper class). - Also, one should always remember to correctly set and unset (where the - latter simply involved a call to ThreadLocal.set(null)) the resource - local to the thread. Unsetting should be done in any case since not - unsetting it might result in problematic behavior. Spring's ThreadLocal - support does this for you and should always be considered in favor - of using ThreadLocals without other proper handling - code. - + + ThreadLocals come with serious issues (potentially + resulting in memory leaks) when incorrectly using them in a + multi-threaded and multi-classloader environments. One should always + consider wrapping a threadlocal in some other class and never directly + use the ThreadLocal itself (except of course in the wrapper class). + Also, one should always remember to correctly set and unset (where the + latter simply involved a call to ThreadLocal.set(null)) the resource + local to the thread. Unsetting should be done in any case since not + unsetting it might result in problematic behavior. Spring's ThreadLocal + support does this for you and should always be considered in favor + of using ThreadLocals without other proper handling + code. +
-
+
Defining new <interfacename>Advice</interfacename> types Spring AOP is designed to be extensible. While the interception @@ -1931,7 +1929,7 @@ System.out.println("Max pool size is " + conf.getMaxSize());]]> Javadocs for further information.
-
+
Further resources Please refer to the Spring sample applications for further examples diff --git a/src/reference/docbook/classic-spring.xml b/src/reference/docbook/classic-spring.xml index 07d67305bb..fe44039b83 100644 --- a/src/reference/docbook/classic-spring.xml +++ b/src/reference/docbook/classic-spring.xml @@ -1,8 +1,12 @@ - + 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"> Classic Spring Usage 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. -
+
Classic ORM usage 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 chapter. -
+
Hibernate For the currently recommended usage patterns for Hibernate see -
+
The <classname>HibernateTemplate</classname> 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); } } @@ -117,7 +121,7 @@ }
-
+
Implementing Spring-based DAOs without callbacks As alternative to using Spring's @@ -170,13 +174,13 @@
-
+
JDO For the currently recommended usage patterns for JDO see -
+
<classname>JdoTemplate</classname> and <classname>JdoDaoSupport</classname> @@ -189,15 +193,15 @@ JdoTemplate: <beans> - + <bean id="myProductDao" class="product.ProductDaoImpl"> <property name="persistenceManagerFactory" ref="myPmf"/> </bean> - + </beans> 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); // do some further stuff with the result list return result; @@ -237,7 +241,7 @@ typical requirements: 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 @@
-
+
JPA For the currently recommended usage patterns for JPA see -
+
<classname>JpaTemplate</classname> and <classname>JpaDaoSupport</classname> @@ -282,7 +286,7 @@ </beans> 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(); // do some further processing with the result list return result; } @@ -322,7 +326,7 @@ subclasses: 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 @@
-
+
Classic Spring MVC ...
-
+
JMS Usage One of the benefits of Spring's JMS support is to shield the user @@ -392,7 +396,7 @@ -
+
JmsTemplate Located in the package @@ -407,7 +411,7 @@ that the point-to-point domain, Queues, will be used.
-
+
Asynchronous Message Reception
-
+
Connections The ConnectionFactory interface is part of @@ -441,7 +445,7 @@ javax.jmsTopicConnection.
-
+
Transaction Management In a JMS 1.0.2 environment the class diff --git a/src/reference/docbook/dao.xml b/src/reference/docbook/dao.xml index cf9cdae651..12d0c487af 100644 --- a/src/reference/docbook/dao.xml +++ b/src/reference/docbook/dao.xml @@ -1,11 +1,15 @@ - + 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"> DAO support -
+
Introduction The Data Access Object (DAO) support in Spring is aimed at making it @@ -16,7 +20,7 @@ to each technology.
-
+
Consistent exception hierarchy Spring provides a convenient translation from technology-specific @@ -71,7 +75,7 @@
-
+
Annotations used for configuring DAO or Repository classes 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; - + // ... } @@ -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; } - + // ... } @@ -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); } - + // ... } diff --git a/src/reference/docbook/dtd.xml b/src/reference/docbook/dtd.xml index 79bbae2628..accfc0d67f 100644 --- a/src/reference/docbook/dtd.xml +++ b/src/reference/docbook/dtd.xml @@ -1,62 +1,66 @@ - + 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"> <literal>spring-beans-2.0.dtd</literal> <!-- - 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> diff --git a/src/reference/docbook/dynamic-languages.xml b/src/reference/docbook/dynamic-languages.xml index 7a6683fb7d..f2f94889a8 100644 --- a/src/reference/docbook/dynamic-languages.xml +++ b/src/reference/docbook/dynamic-languages.xml @@ -1,11 +1,15 @@ - + 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"> Dynamic language support -
+
Introduction Why only these languages? @@ -19,7 +23,7 @@ There is nothing stopping the inclusion of further languages though. If you want to see support for <insert your favourite dynamic language here>, you can always raise an issue on Spring's - JIRA + JIRA page (or implement such support yourself). @@ -51,7 +55,7 @@
-
+
A first example This bulk of this chapter is concerned with describing the dynamic language support @@ -68,7 +72,7 @@ Messenger won't know that the underlying implementation is a Groovy script. - Messenger interface. - Here is an implementation of the Messenger interface in Groovy. - - ]]><!-- this is the bean definition for the Groovy-backed Messenger implementation --><!-- this is the bean definition for the Groovy-backed Messenger implementation --> - ]]><!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger --><!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger --> @@ -156,7 +160,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
-
+
Defining beans that are backed by dynamic languages 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 at the end of this chapter. -
+
Common concepts The steps involved in using dynamic-language-backed beans are as follows: @@ -205,7 +209,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema language source files. -
+
The <literal><lang:language/></literal> element XML Schema @@ -252,7 +256,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
-
+
Refreshable beans One of the (if not the) 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. - Messenger.groovy source file when the execution of the program is paused. -
-
+
Inline dynamic language source files The dynamic language support can also cater for dynamic language @@ -451,14 +455,14 @@ class RubyMessenger < Messenger def getMessage @@message end - + end ]]>
-
+
Understanding Constructor Injection in the context of dynamic-language-backed beans There is one very important thing to be aware of @@ -469,7 +473,7 @@ end properties 100% clear, the following mixture of code and configuration will not work. - ]]> - <!-- this next constructor argument will *not* be injected into the GroovyMessenger --> + <!-- this next constructor argument will *not* be injected into the GroovyMessenger --> <!-- in fact, this isn't even allowed according to the schema -->This will *not* work]]> - - <!-- only property values are injected into the dynamic-language-backed object -->This will *not* work]]> + + <!-- only property values are injected into the dynamic-language-backed object --> ]]> @@ -507,7 +511,7 @@ class GroovyMessenger implements Messenger {
-
+
JRuby beans @@ -523,9 +527,11 @@ class GroovyMessenger implements Messenger { From the JRuby homepage... + JRuby is an 100% pure-Java implementation of the Ruby programming language. + 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). - - - + ]]> @@ -591,7 +597,7 @@ RubyMessenger.new]]> can achieve this by simply instantiating a new instance of your JRuby class on the last line of the source file like so: - and the following text is there in the corresponding stacktrace, this will hopefully allow you to identify and then easily rectify the issue): + + 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]]>
-
+
Groovy beans The Groovy library dependencies @@ -649,19 +657,21 @@ RubyMessenger.new]]> From the Groovy homepage... + 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. + If you have read this chapter straight from the top, you will already have seen an example of a Groovy-dynamic-language-backed bean. Let's look at another example (again using an example from the Spring test suite). - Calculator interface in Groovy. - // from the file 'calculator.groovy'// from the file 'calculator.groovy' Lastly, here is a small application to exercise the above configuration. - -
+
Customising Groovy objects via a callback The GroovyObjectCustomizer @@ -726,7 +736,7 @@ public class Main { any required initialization method(s), or set some default property values, or specify a custom MetaClass. - @@ -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. - GroovyObjectCustomizer is easy if you are using the Spring 2.0 namespace support. - <!-- define the GroovyObjectCustomizer just like any other bean --> + <!-- define the GroovyObjectCustomizer just like any other bean --> - ]]><!-- ... and plug it into the desired Groovy bean via the 'customizer-ref' attribute --><!-- ... and plug it into the desired Groovy bean via the 'customizer-ref' attribute -->]]> @@ -775,7 +785,7 @@ public class Main { - ]]><!-- define the GroovyObjectCustomizer (as an inner bean) --><!-- define the GroovyObjectCustomizer (as an inner bean) --> @@ -785,7 +795,7 @@ public class Main {
-
+
BeanShell beans The BeanShell library dependencies @@ -800,6 +810,7 @@ public class Main { From the BeanShell homepage... + 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. + 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). - Here is the BeanShell 'implementation' (the term is used loosely here) of the Messenger interface. -
-
+
Scenarios 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. -
+
Scripted Spring MVC Controllers One group of classes that may benefit from using dynamic-language-backed @@ -903,7 +915,7 @@ void setMessage(String aMessage) { org.springframework.web.servlet.mvc.Controller implemented using the Groovy dynamic language. -
-
+
Scripted Validators Another area of application development with Spring that may benefit @@ -952,7 +964,7 @@ class FortuneController implements Controller { 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 for a full and detailed treatment of this feature. @@ -963,7 +975,7 @@ class FortuneController implements Controller { implemented using the Groovy dynamic language. (See for a discussion of the Validator interface.) - 0) { return @@ -983,14 +995,14 @@ class TestBeanValidator implements Validator {
-
+
Bits and bobs This last section contains some bits and bobs related to the dynamic language support. -
+
AOP - advising scripted beans It is possible to use the Spring AOP framework to advise scripted beans. @@ -1009,7 +1021,7 @@ class TestBeanValidator implements Validator {
-
+
Scoping 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"> - scope="prototype" + scope="prototype" @@ -1048,7 +1060,7 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema
-
+
Further Resources 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 - The JRuby homepage + The JRuby homepage - The Groovy homepage + The Groovy homepage - The BeanShell homepage + The BeanShell homepage @@ -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 - Spring Modules project. + Spring Modules project.
diff --git a/src/reference/docbook/ejb.xml b/src/reference/docbook/ejb.xml index cec60c2123..3ebf18a009 100644 --- a/src/reference/docbook/ejb.xml +++ b/src/reference/docbook/ejb.xml @@ -1,11 +1,15 @@ - - Enterprise JavaBeans (EJB) 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"> + Enterprise JavaBeans (EJB) integration -
+
Introduction 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. -
+
-
- Accessing EJBs +
+ Accessing EJBs -
- Concepts - - 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. +
+ Concepts + + 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. - - 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: + + 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: - - - - Typically code using EJBs depends on Service Locator or - Business Delegate singletons, making it hard to test. - - - - - 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. - - - - - 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. - - - - - 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. - -
+ + + + Typically code using EJBs depends on Service Locator or + Business Delegate singletons, making it hard to test. + + + + + 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. + + + + + 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. + + + + + 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. + +
-
- Accessing local SLSBs - - 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 MyComponent. - - + Accessing local SLSBs + + 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 MyComponent. + + - - 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 SessionBean - and the MyComponent 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 MyComponent - on the controller. This will save the reference as an instance variable in the - controller: - - + 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 SessionBean + and the MyComponent 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 MyComponent + on the controller. This will save the reference as an instance variable in the + controller: + + - - 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 - LocalStatelessSessionProxyFactoryBean instance, which - will be the EJB proxy object. The configuration of the proxy, and setting of - the myComponent property of the controller is done - with a configuration entry such as: - - + 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 + LocalStatelessSessionProxyFactoryBean instance, which + will be the EJB proxy object. The configuration of the proxy, and setting of + the myComponent property of the controller is done + with a configuration entry such as: + + @@ -131,21 +135,21 @@ public void setMyComponent(MyComponent myComponent) { ]]> - - 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 myComponent 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 classname method on the local EJB and - invokes the corresponding business method on the EJB. - - - The myController bean definition sets the - myComponent property of the controller class to the - EJB proxy. - + + 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 myComponent 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 classname method on the local EJB and + invokes the corresponding business method on the EJB. + + + The myController bean definition sets the + myComponent property of the controller class to the + EJB proxy. + Alternatively (and preferably in case of many such proxy definitions), consider using the <jee:local-slsb> @@ -157,87 +161,87 @@ public void setMyComponent(MyComponent myComponent) { ]]> - - 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 myComponent 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. - - - 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. - - - 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 - ApplicationContext 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 init() 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 lazy-init attribute. - - - 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 - LocalSlsbInvokerInterceptor. - -
+ + 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 myComponent 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. + + + 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. + + + 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 + ApplicationContext 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 init() 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 lazy-init attribute. + + + 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 + LocalSlsbInvokerInterceptor. + +
-
- Accessing remote SLSBs - - Accessing remote EJBs is essentially identical to accessing local - EJBs, except that the - SimpleRemoteStatelessSessionProxyFactoryBean or +
+ Accessing remote SLSBs + + Accessing remote EJBs is essentially identical to accessing local + EJBs, except that the + SimpleRemoteStatelessSessionProxyFactoryBean or <jee:remote-slsb> 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. - - - 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 RemoteException, 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 - RemoteException in your Business Method Interface and - implementing EJB code, have a remote interface which is identical except - that it does throw RemoteException, 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 - RemoteException class. Any actual - RemoteException that is thrown during the EJB - invocation will be re-thrown as the non-checked - RemoteAccessException class, which is a subclass of - RuntimeException. 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 - RemoteExceptions in your business interface. - -
+ 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. +
+ + 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 RemoteException, 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 + RemoteException in your Business Method Interface and + implementing EJB code, have a remote interface which is identical except + that it does throw RemoteException, 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 + RemoteException class. Any actual + RemoteException that is thrown during the EJB + invocation will be re-thrown as the non-checked + RemoteAccessException class, which is a subclass of + RuntimeException. 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 + RemoteExceptions in your business interface. + +
-
+
Accessing EJB 2.x SLSBs versus EJB 3 SLSBs 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.
-
+
-
- Using Spring's EJB implementation support classes +
+ Using Spring's EJB implementation support classes -
+
EJB 2.x base classes Spring provides convenience classes to help you implement EJBs. @@ -391,7 +395,7 @@ public void setMyComponent(MyComponent myComponent) {
-
+
EJB 3 injection interceptor For EJB 3 Session Beans and Message-Driven Beans, Spring provides a convenient @@ -434,6 +438,6 @@ public class MyFacadeEJB implements MyFacadeLocal {
-
+
diff --git a/src/reference/docbook/expressions.xml b/src/reference/docbook/expressions.xml index 65733511c6..5dcafe7e14 100644 --- a/src/reference/docbook/expressions.xml +++ b/src/reference/docbook/expressions.xml @@ -1,11 +1,15 @@ - + 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"> Spring Expression Language (SpEL) -
+
Introduction The Spring Expression Language (SpEL for short) is a powerful @@ -44,7 +48,7 @@ the end of the chapter.
-
+
Feature Overview The expression language supports the following functionality @@ -85,16 +89,16 @@ Calling constructors - + Bean references - + Array construction - - + + Inline lists @@ -124,12 +128,12 @@
-
+
Expression Evaluation using Spring's Expression Interface This section introduces the simple use of SpEL interfaces and its expression language. The complete language reference can be found in the - section Language + section Language Reference. The following code introduces the SpEL API to evaluate the literal @@ -173,7 +177,7 @@ String message = (String) exp.getValue(); ExpressionParser parser = new SpelExpressionParser(); // invokes 'getBytes()' -Expression exp = parser.parseExpression("'Hello World'.bytes"); +Expression exp = parser.parseExpression("'Hello World'.bytes"); byte[] bytes = (byte[]) exp.getValue(); @@ -185,7 +189,7 @@ byte[] bytes = (byte[]) exp.getValue(); ExpressionParser parser = new SpelExpressionParser(); // invokes 'getBytes().length' -Expression exp = parser.parseExpression("'Hello World'.bytes.length"); +Expression exp = parser.parseExpression("'Hello World'.bytes.length"); int length = (Integer) exp.getValue(); @@ -204,14 +208,14 @@ String message = exp.getValue(String.class); the registered type converter. 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 name property from an instance of the Inventor class. - // Create and set a calendar + // Create and set a calendar GregorianCalendar c = new GregorianCalendar(); c.set(1856, 7, 9); @@ -229,10 +233,10 @@ String name = (String) exp.getValue(context); 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 getValue, + repeatedly, it can be supplied on each call to getValue, as this next example shows: - - / Create and set a calendar + + / Create and set a calendar GregorianCalendar c = new GregorianCalendar(); c.set(1856, 7, 9); @@ -245,13 +249,13 @@ Expression exp = parser.parseExpression("name") String name = (String) exp.getValue(tesla); In this case the inventor tesla has been supplied directly to getValue 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. - + 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. 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. - + 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. - 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. Expression exp = parser.parseExpression("name == 'Nikola Tesla'"); boolean result = exp.getValue(context, Boolean.class); // evaluates to true -
+
The EvaluationContext interface The interface EvaluationContext is @@ -297,7 +301,7 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to truesetVariable() and registerFunction(). The use of variables and functions are described in the language reference sections Variables and Variables and Functions. The StandardEvaluationContext is also where you can register custom ConstructorResolvers, @@ -306,7 +310,7 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to true -
+
Type Conversion By default SpEL uses the conversion service available in Spring @@ -330,14 +334,14 @@ boolean result = exp.getValue(context, Boolean.class); // evaluates to trueclass 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);
-
+
Expression support for defining bean definitions 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 #{ <expression string> }. -
+
XML based configuration A property or constructor-arg value can be set using expressions @@ -395,7 +399,7 @@ Boolean b = simple.booleanList.get(0); </bean>
-
+
Annotation-based configuration The @Value 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);
-
+
Language Reference -
+
Literal expressions The types of literal expressions supported are strings, dates, @@ -497,12 +501,12 @@ Boolean b = simple.booleanList.get(0); 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().
-
+
Properties, Arrays, Lists, Maps, Indexers Navigating with property references is easy, just use a period to @@ -524,8 +528,8 @@ Object nullValue = parser.parseExpression("null").getValue(); examples. To navigate "down" and get Tesla's year of birth and Pupin's city of birth the following expressions are used. - // evals to 1856 -int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context); + // evals to 1856 +int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context); String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context); @@ -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 // 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(
-
+
Inline lists Lists can be expressed directly in an expression using {} notation. - + // 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); {} 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. -
- -
+
+ +
Array construction Arrays can be built using the familiar Java syntax, optionally supplying an initializer to have the array populated at construction time. - int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context); + 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); It is not currently allowed to supply an initializer when constructing a multi-dimensional array. -
- -
+
+ +
Methods Methods are invoked using typical Java programming syntax. You may @@ -626,10 +630,10 @@ boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue( Boolean.class);
-
+
Operators -
+
Relational operators 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); 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.
-
+
Logical operators 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);
-
+
Mathematical operators The addition operator can be used on numbers, strings and dates. @@ -714,7 +718,7 @@ boolean falseValue = parser.parseExpression(expression).getValue(societyContext, // 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);
-
+
Assignment 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); setValue but can also be done inside a call to getValue. - Inventor inventor = new Inventor(); + 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);
-
+
Types 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);
-
+
Constructors 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). - Inventor einstein = - p.parseExpression("new org.spring.samples.spel.inventor.Inventor('Albert Einstein', + 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
-
+
Variables 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" -
+
The #this and #root variables 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);
-
+
Functions 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 = 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);
-
- Bean references - If the evaluation context has been configured with a bean resolver it is possible to - lookup beans from an expression using the (@) symbol. - +
+ Bean references + If the evaluation context has been configured with a bean resolver it is possible to + lookup beans from an expression using the (@) symbol. + 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);
- -
+ +
Ternary Operator (If-Then-Else) You can use the ternary operator for performing if-then-else conditional logic inside the expression. A minimal example is: - String falseString = + String falseString = parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(String.class); In this case, the boolean false results in returning the string @@ -934,10 +938,10 @@ Object bean = parser.parseExpression("@foo").getValue(context); 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" @@ -945,12 +949,11 @@ String queryResultString = shorter syntax for the ternary operator.
-
+
The Elvis Operator The Elvis operator is a shortening of the ternary operator syntax - and is used in the Groovy + and is used in the Groovy language. With the ternary operator syntax you usually have to repeat a variable twice, for example: @@ -986,12 +989,12 @@ name = parser.parseExpression("Name?:'Elvis Presley'").getValue(context, String. System.out.println(name); // Elvis Presley
-
+
Safe Navigation operator The Safe Navigation operator is used to avoid a - NullPointerException and comes from the Groovy + NullPointerException and comes from the Groovy 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!!!
-
+
Collection Selection Selection is a powerful expression language feature that allows you @@ -1036,7 +1039,7 @@ System.out.println(city); // null - does not throw NullPointerException!!! - List<Inventor> list = (List<Inventor>) + List<Inventor> list = (List<Inventor>) parser.parseExpression("Members.?[Nationality == 'Serbian']").getValue(societyContext); 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!!!$[...].
-
+
Collection Projection 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.
-
+
Expression templating 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 #{ } as the delimiters. For example, - String randomPhrase = - parser.parseExpression("random number is #{T(java.lang.Math).random()}", + String randomPhrase = + parser.parseExpression("random number is #{T(java.lang.Math).random()}", new TemplateParserContext()).getValue(String.class); // evaluates to "random number is 0.7038186818312008" @@ -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]"
-
+
Classes used in the examples Inventor.java @@ -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; - } + } } @@ -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; + } + + - - } @@ -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; - } - }
diff --git a/src/reference/docbook/index.xml b/src/reference/docbook/index.xml index 50b2075d34..b12b9e83df 100644 --- a/src/reference/docbook/index.xml +++ b/src/reference/docbook/index.xml @@ -1,10 +1,15 @@ - - - Spring Framework Reference Manual + 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"> + + + Spring Framework Reference Documentation Spring Framework @@ -19,171 +24,199 @@ - Rod - - Johnson + + Rod + Johnson + - Juergen - - Hoeller + + Juergen + Hoeller + - Keith - - Donald + + Keith + Donald + - Colin - - Sampaleanu + + Colin + Sampaleanu + - Rob - - Harrop + + Rob + Harrop + - Thomas - - Risberg + + Thomas + Risberg + - Alef - - Arendsen + + Alef + Arendsen + - Darren - - Davison + + Darren + Davison + - Dmitriy - - Kopylenko + + Dmitriy + Kopylenko + - Mark - - Pollack + + Mark + Pollack + - Thierry - - Templier + + Thierry + Templier + - Erwin - - Vervaet + + Erwin + Vervaet + - Portia - - Tung + + Portia + Tung + - Ben - - Hale + + Ben + Hale + - Adrian - - Colyer + + Adrian + Colyer + - John - - Lewis + + John + Lewis + - Costin - - Leau + + Costin + Leau + - Mark - - Fisher + + Mark + Fisher + - Sam - - Brannen + + Sam + Brannen + - Ramnivas - - Laddad + + Ramnivas + Laddad + - Arjen - - Poutsma + + Arjen + Poutsma + - Chris - - Beams + + Chris + Beams + - Tareq - - Abedrabbo + + Tareq + Abedrabbo + - Andy - - Clement + + Andy + Clement + - Dave - - Syer - - - - Oliver - - Gierke + + Dave + Syer + - Rossen - - Stoyanchev + + Oliver + Gierke + - Phillip + + Rossen + Stoyanchev + + - Webb + + + Phillip + Webb + @@ -206,16 +239,16 @@ copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. - + - + Overview of Spring Framework - + 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 @@ 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 - . + . - + What's New in Spring 3 @@ -254,10 +287,10 @@ - + Core Technologies - + This part of the reference documentation covers all of those technologies that are absolutely integral to the Spring Framework. @@ -334,10 +367,10 @@ - + Data Access - + 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. @@ -382,10 +415,10 @@ - + The Web - + This part of the reference documentation covers the Spring Framework's support for the presentation tier (and specifically web-based presentation tiers). @@ -430,10 +463,10 @@ - + Integration - + This part of the reference documentation covers the Spring Framework's integration with a number of Java EE (and related) technologies. @@ -494,12 +527,12 @@ - + - + Appendices - + 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"> Data access with JDBC -
+
Introduction to Spring Framework JDBC The value-add provided by the Spring Framework JDBC abstraction is @@ -122,7 +126,7 @@ The Spring Framework takes care of all the low-level details that can make JDBC such a tedious API to develop with. -
+
Choosing an approach for JDBC database access You can choose among several approaches to form the basis for your @@ -166,7 +170,7 @@ SimpleJdbcCall 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. 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
-
+
Package hierarchy<!--I have provided links to main sections that deal with most packages. TR: OK--> 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
-
+
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--> -
+
<classname>JdbcTemplate</classname> The JdbcTemplate 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 JdbcTemplate class). -
+
Examples of JdbcTemplate class usage This section provides some examples of @@ -302,7 +306,7 @@ TR: OK. I removed the sentence since it isn;t entirely accurate. The implementat JdbcTemplate; see the attendant Javadocs for that. -
+
Querying (SELECT) 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 Querying for a String: 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); Querying and populating a single 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; - } + } }
-
+
Updating (INSERT/UPDATE/DELETE) with jdbcTemplate<!--Provide introductory text as with other examples. TR: OK.--> You use the update(..) method to @@ -383,11 +387,11 @@ private static final class ActorMapper implements RowMapper<Actor> { array. this.jdbcTemplate.update( - "insert into t_actor (first_name, last_name) values (?, ?)", + "insert into t_actor (first_name, last_name) values (?, ?)", "Leonor", "Watling"); this.jdbcTemplate.update( - "update t_actor set = ? where id = ?", + "update t_actor set = ? where id = ?", "Banjo", 5276L); this.jdbcTemplate.update( @@ -395,7 +399,7 @@ private static final class ActorMapper implements RowMapper<Actor> { Long.valueOf(actorId));
-
+
Other jdbcTemplate operations You can use the execute(..) method to @@ -410,12 +414,12 @@ private static final class ActorMapper implements RowMapper<Actor> { linkend="jdbc-StoredProcedure">covered later. this.jdbcTemplate.update( - "call SUPPORT.REFRESH_ACTORS_SUMMARY(?)", + "call SUPPORT.REFRESH_ACTORS_SUMMARY(?)", Long.valueOf(unionId));
-
+
<classname>JdbcTemplate</classname> best practices Instances of the JdbcTemplate class are @@ -448,7 +452,7 @@ private static final class ActorMapper implements RowMapper<Actor> { this.jdbcTemplate = new JdbcTemplate(dataSource); } - // JDBC-backed implementations of the methods on the CorporateEventDao follow... + // JDBC-backed implementations of the methods on the CorporateEventDao follow... } The corresponding configuration might look like this. @@ -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 { this.jdbcTemplate = new JdbcTemplate(dataSource); } - // JDBC-backed implementations of the methods on the CorporateEventDao follow... + // JDBC-backed implementations of the methods on the CorporateEventDao follow... } The corresponding XML configuration file 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 {
-
+
<classname>NamedParameterJdbcTemplate</classname> The NamedParameterJdbcTemplate class adds @@ -614,8 +618,9 @@ public int countOfActorsByFirstName(String firstName) { same Java package) is the SqlParameterSource interface. You have already seen an example of an implementation of this interface in one of the previous code snippet (the - MapSqlParameterSource class). An - SqlParameterSource is a source of + MapSqlParameterSource class). + + An SqlParameterSource is a source of named parameter values to a NamedParameterJdbcTemplate. The MapSqlParameterSource class is a very simple @@ -627,9 +632,9 @@ public int countOfActorsByFirstName(String firstName) { implementation is the BeanPropertySqlParameterSource class. This class wraps an arbitrary JavaBean (that is, an instance of a class that - adheres to the JavaBean - conventions), and uses the properties of the wrapped JavaBean as + adheres to the JavaBean + conventions), and uses the properties of the wrapped JavaBean as the source of named parameter values. 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; } - + // setters omitted... } @@ -663,8 +668,8 @@ public void setDataSource(DataSource dataSource) { public int countOfActors(Actor exampleActor) { - // notice how the named parameters match the properties of the above 'Actor' class - String sql = + // notice how the named parameters match the properties of the above 'Actor' class + 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.
-
+
<classname>SimpleJdbcTemplate</classname> The SimpleJdbcTemplate class wraps the @@ -713,7 +718,7 @@ public int countOfActors(Actor exampleActor) { code snippet that does the same job with the SimpleJdbcTemplate. - // classic JdbcTemplate-style... + // classic JdbcTemplate-style... private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { @@ -722,9 +727,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>() { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); @@ -735,16 +740,16 @@ public Actor findActor(String specialty, int age) { } }; - + // notice the wrapping up of the arguments in an array return (Actor) jdbcTemplate.queryForObject(sql, new Object[] {specialty, age}, mapper); } Here is the same method, with the - SimpleJdbcTemplate. - // SimpleJdbcTemplate-style... + // SimpleJdbcTemplate-style... 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) { } }; - // notice the use of varargs since the parameter values now come + // notice the use of varargs since the parameter values now come // after the RowMapper parameter return this.simpleJdbcTemplate.queryForObject(sql, mapper, specialty, age); } @@ -789,7 +794,7 @@ public Actor findActor(String specialty, int age) {
-
+
<interfacename>SQLExceptionTranslator</interfacename> SQLExceptionTranslator is an @@ -891,29 +896,29 @@ public Actor findActor(String specialty, int age) { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { - // create a JdbcTemplate and set data source - this.jdbcTemplate = new JdbcTemplate(); - this.jdbcTemplate.setDataSource(dataSource); - // create a custom translator and set the DataSource for the default translation lookup - CustomSQLErrorCodesTranslator tr = new CustomSQLErrorCodesTranslator(); - tr.setDataSource(dataSource); - this.jdbcTemplate.setExceptionTranslator(tr); + // create a JdbcTemplate and set data source + this.jdbcTemplate = new JdbcTemplate(); + this.jdbcTemplate.setDataSource(dataSource); + // create a custom translator and set the DataSource for the default translation lookup + CustomSQLErrorCodesTranslator tr = new CustomSQLErrorCodesTranslator(); + tr.setDataSource(dataSource); + this.jdbcTemplate.setExceptionTranslator(tr); } public void updateShippingCharge(long orderId, long pct) { - // use the prepared JdbcTemplate for this update + // use the prepared JdbcTemplate for this update 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); } The custom translator is passed a data source in order to look up the error codes in sql-error-codes.xml.
-
+
Executing statements Executing an SQL statement requires very little code. You need a @@ -941,7 +946,7 @@ public class ExecuteAStatement { }
-
+
Running queries 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() { [{name=Bob, id=1}, {name=Mary, id=2}]
-
+
Updating the database 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); } }
-
+
Retrieving auto-generated keys An update() convenience method - supports 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(
-
+
Controlling database connections -
+
<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.--> Spring obtains a connection to the database through a @@ -1137,7 +1142,7 @@ dataSource.setPassword(""); DBCP configuration: - <bean id="dataSource" + <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(""); <context:property-placeholder location="jdbc.properties"/>
-
+
<classname>DataSourceUtils</classname> The DataSourceUtils class is a convenient @@ -1170,7 +1175,7 @@ dataSource.setPassword(""); DataSourceTransactionManager.
-
+
<interfacename>SmartDataSource</interfacename> The SmartDataSource interface @@ -1182,11 +1187,11 @@ dataSource.setPassword(""); connection.
-
+
<classname>AbstractDataSource</classname> AbstractDataSource is an - abstract base class for + abstract base class for Spring's DataSource implementations that implements code that is common to all DataSource implementations. @@ -1195,7 +1200,7 @@ dataSource.setPassword(""); implementation.
-
+
<classname>SingleConnectionDataSource</classname> The SingleConnectionDataSource class is an @@ -1222,7 +1227,7 @@ dataSource.setPassword(""); connections.
-
+
<classname>DriverManagerDataSource</classname> The DriverManagerDataSource class is an @@ -1244,7 +1249,7 @@ dataSource.setPassword(""); DriverManagerDataSource.
-
+
<classname>TransactionAwareDataSourceProxy</classname> TransactionAwareDataSourceProxy is a proxy @@ -1272,7 +1277,7 @@ dataSource.setPassword(""); details.)
-
+
<classname>DataSourceTransactionManager</classname> The DataSourceTransactionManager class is a @@ -1307,7 +1312,7 @@ dataSource.setPassword(""); isolation levels!
-
+
NativeJdbcExtractor Sometimes you need to access vendor specific JDBC methods that @@ -1360,7 +1365,7 @@ dataSource.setPassword("");
-
+
JDBC batch operations Most JDBC drivers provide improved performance if you batch multiple @@ -1369,7 +1374,7 @@ dataSource.setPassword(""); processing using both the JdbcTemplate and the SimpleJdbcTemplate. -
+
Basic batch operations with the JdbcTemplate You accomplish JdbcTemplate batch @@ -1419,7 +1424,7 @@ dataSource.setPassword(""); you to signal the end of the batch.
-
+
Batch operations with a List of objects Both the JdbcTemplate and the @@ -1490,7 +1495,7 @@ dataSource.setPassword(""); driver returns a -2 value.
-
+
Batch operations with multiple batches The last example of a batch update deals with batches that are so @@ -1525,7 +1530,7 @@ dataSource.setPassword(""); ps.setString(1, argument.getFirstName()); ps.setString(2, argument.getLastName()); ps.setLong(3, argument.getId().longValue()); - + } } ); return updateCounts; @@ -1545,7 +1550,7 @@ dataSource.setPassword("");
-
+
Simplifying JDBC operations with the SimpleJdbc classes The SimpleJdbcInsert and @@ -1555,14 +1560,14 @@ dataSource.setPassword(""); up front, although you can override or turn off the metadata processing if you prefer to provide all the details in your code. -
+
Inserting data using SimpleJdbcInsert Let's start by looking at the SimpleJdbcInsert class with the minimal amount of configuration options. You should instantiate the SimpleJdbcInsert in the data access layer's - initialization method. For this example, the initializing method is the setDataSource method. You do not need to subclass the SimpleJdbcInsert 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.
-
+
Retrieving auto-generated keys using SimpleJdbcInsert 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.
-
+
Specifying columns for a SimpleJdbcInsert 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.
-
+
Using SqlParameterSource to provide parameter values Using a Map to provide parameter values @@ -1741,7 +1746,7 @@ TR: Revised, please review.-->For this example, the initializing method is the classes.
-
+
Calling a stored procedure with SimpleJdbcCall The SimpleJdbcCall class leverages metadata @@ -1756,14 +1761,14 @@ TR: Revised, please review.-->For this example, the initializing method is the last_name, and birth_date columns in the form of out parameters. - 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 + 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;The in_id parameter contains the id of the actor you are looking up. The out @@ -1793,7 +1798,7 @@ END;The in_id 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;The in_id parameter contains the // ... additional methods }The code you write for the execution of the call involves creating an SqlParameterSource containing the IN - parameter. It's important to match the name provided for the input value with that of the parameter name declared @@ -1858,7 +1863,7 @@ TR: Revised, please review. Execution is separate from declaration, so we still for the names of your returned out parameters.
-
+
Explicitly declaring parameters to use for a SimpleJdbcCall @@ -1919,7 +1924,7 @@ TR: Revised, please review. Execution is separate from declaration, so we still metadata.
-
+
How to define SqlParameters 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.
-
+
Calling a stored function using SimpleJdbcCall 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: 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; 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; the function call.
-
+
Returning ResultSet/REF Cursor from a SimpleJdbcCall Calling a stored procedure or function that returns a result set @@ -2083,7 +2088,7 @@ END;To call this procedure you declare the
-
+
Modeling JDBC operations as Java objects The org.springframework.jdbc.object package @@ -2108,7 +2113,7 @@ END;To call this procedure you declare the operation classes, continue using these classes. -
+
<classname>SqlQuery</classname> SqlQuery is a reusable, threadsafe class @@ -2126,7 +2131,7 @@ END;To call this procedure you declare the UpdatableSqlQuery.
-
+
<classname>MappingSqlQuery</classname> MappingSqlQuery is a reusable query in @@ -2202,7 +2207,7 @@ public Customer getCustomer(Long id) { }
-
+
<classname>SqlUpdate</classname> The SqlUpdate class encapsulates an SQL @@ -2247,7 +2252,7 @@ public class UpdateCreditRating extends SqlUpdate { }
-
+
<classname>StoredProcedure</classname> The StoredProcedure 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 {
-
+
Common problems with parameter and data value handling Common problems with parameters and data values exist in the different approaches provided by the Spring Framework JDBC. -
+
Providing SQL type information for parameters Usually Spring determines the SQL type of the parameters based on @@ -2522,7 +2527,7 @@ public class TitlesAfterDateStoredProcedure extends StoredProcedure {
-
+
Handling BLOB and CLOB objects 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) {]]> new RowMapper>() { public Map mapRow(ResultSet rs, int i) throws SQLException { Map results = new HashMap(); - String clobText = lobHandler.getClobAsString(rs, "a_clob");]]>
-
+
Passing in lists of values for IN clause The SQL standard allows for selecting rows based on an expression @@ -2696,7 +2701,7 @@ clobReader.close();]]> database supports this syntax.
-
+
Handling complex types for stored procedure calls When you call stored procedures you can sometimes use complex @@ -2713,12 +2718,12 @@ clobReader.close();]]> that must be implemented. This interface is used as part of the declaration of an SqlOutParameter. - final TestItem - new TestItem(123L, "A test item", + 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", StructDescriptors, as shown in the following example, or ArrayDescriptors. - final TestItem - new TestItem(123L, "A test item", + 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() {
-
+
Embedded database support The org.springframework.jdbc.datasource.embedded package provides support for embedded Java database engines. Support for - HSQL, H2, and Derby is provided natively. You + HSQL, H2, and Derby is provided natively. You can also use an extensible API to plug in new embedded database types and DataSource implementations. -
+
Why use an embedded database? An embedded database is useful during the development phase of a @@ -2795,7 +2800,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() { rapidly evolve SQL during development.
-
+
Creating an embedded database instance using Spring XML If you want to expose an embedded database instance as a bean in a @@ -2814,7 +2819,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() { needed.
-
+
Creating an embedded database instance programmatically The EmbeddedDatabaseBuilder class provides @@ -2828,7 +2833,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() {
-
+
Extending the embedded database support Spring JDBC embedded database support can be extended in two ways: @@ -2847,11 +2852,11 @@ SqlTypeValue value = new AbstractSqlTypeValue() { You are encouraged to contribute back extensions to the Spring - community at jira.springframework.org. + community at jira.springframework.org.
-
+
Using HSQL Spring supports HSQL 1.8.0 and above. HSQL is the default embedded @@ -2863,7 +2868,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() { EmbeddedDatabaseType.HSQL.
-
+
Using H2 Spring supports the H2 database as well. To enable H2, set the @@ -2874,7 +2879,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() { EmbeddedDatabaseType.H2.
-
+
Using Derby Spring also supports Apache Derby 10.5 and above. To enable Derby, @@ -2885,7 +2890,7 @@ SqlTypeValue value = new AbstractSqlTypeValue() { EmbeddedDatabaseType.Derby.
-
+
Testing data access logic with an embedded database 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 {
-
+
Initializing a DataSource The org.springframework.jdbc.datasource.init @@ -2929,7 +2934,7 @@ public class DataAccessUnitTestTemplate { DataSource for an application, but sometimes you need to initialize an instance running on a server somewhere. -
+
Initializing a database instance using Spring XML If you want to initialize a database and you can provide a @@ -2993,7 +2998,7 @@ public class DataAccessUnitTestTemplate { can simply use the DataSourceInitializer directly, and define it as a component in your application. -
+
Initialization of Other Components that Depend on the Database diff --git a/src/reference/docbook/jms.xml b/src/reference/docbook/jms.xml index 20d3bb9e5c..a4a1bbc094 100644 --- a/src/reference/docbook/jms.xml +++ b/src/reference/docbook/jms.xml @@ -1,11 +1,15 @@ - + 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"> JMS (Java Message Service) -
+
Introduction Spring provides a JMS integration framework that simplifies the use @@ -60,10 +64,10 @@ Spring's transaction management mechanisms.
-
+
Using Spring JMS -
+
<classname>JmsTemplate</classname> The JmsTemplate class is the central class @@ -118,7 +122,7 @@
-
+
Connections The JmsTemplate requires a reference to a @@ -140,7 +144,7 @@ should ensure that it references the managed implementation of the ConnectionFactory. -
+
Caching Messaging Resources The standard API involves creating many intermediate objects. To @@ -154,7 +158,7 @@ IConnectionFactory are provided.
-
+
SingleConnectionFactory Spring provides an implementation of the @@ -171,7 +175,7 @@ from JNDI.
-
+
CachingConnectionFactory The CachingConnectionFactory extends the @@ -193,7 +197,7 @@
-
+
Destination Management Destinations, like ConnectionFactories, are JMS administered @@ -255,7 +259,7 @@ destination.
-
+
Message Listener Containers One of the most common uses of JMS messages in the EJB world is to @@ -279,7 +283,7 @@ There are two standard JMS message listener containers packaged with Spring, each with its specialised feature set. -
+
SimpleMessageListenerContainer 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.
-
+
DefaultMessageListenerContainer This message listener container is the one used in most cases. @@ -309,7 +313,7 @@
-
+
Transaction management Spring provides a JmsTransactionManager @@ -358,7 +362,7 @@
-
+
Sending a <interfacename>Message</interfacename> The JmsTemplate contains many convenience @@ -420,7 +424,7 @@ public class JmsQueueSender { a default destination, the send(MessageCreator c) sends a message to that destination. -
+
Using Message Converters 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} - } + } }
-
+
<interfacename>SessionCallback</interfacename> and <interfacename>ProducerCallback</interfacename> @@ -508,10 +512,10 @@ public class JmsQueueSender {
-
+
Receiving a message -
+
Synchronous Reception 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.
-
+
Asynchronous Reception - Message-Driven POJOs In a fashion similar to a Message-Driven Bean (MDB) in the EJB @@ -584,7 +588,7 @@ public class ExampleListener implements MessageListener { implementation.
-
+
The <interfacename>SessionAwareMessageListener</interfacename> interface @@ -627,7 +631,7 @@ public interface SessionAwareMessageListener { exceptions thrown.
-
+
The <classname>MessageListenerAdapter</classname> The MessageListenerAdapter class is the @@ -709,7 +713,7 @@ public interface SessionAwareMessageListener { <bean class="jmsexample.DefaultTextMessageDelegate"/> </constructor-arg> <property name="defaultListenerMethod" value="receive"/> - <!-- we don't want automatic message context extraction --> + <!-- we don't want automatic message context extraction --> <property name="messageConverter"> <null/> </property> @@ -727,7 +731,7 @@ public interface SessionAwareMessageListener { public interface ResponsiveTextMessageDelegate { - // notice the return type... + // notice the return type... String receive(TextMessage message); } @@ -755,7 +759,7 @@ public interface SessionAwareMessageListener { the call stack).
-
+
Processing messages within transactions Invoking a message listener within a transaction only requires @@ -811,7 +815,7 @@ public interface SessionAwareMessageListener {
-
+
Support for JCA Message Endpoints Beginning with version 2.5, Spring also provides support for a @@ -906,7 +910,7 @@ public interface SessionAwareMessageListener {
-
+
JMS Namespace Support 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 http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd"> -<!-- <bean/> definitions here --> +<!-- <bean/> definitions here --> </beans> @@ -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: - +
Attributes of the JMS <literal><listener></literal> element @@ -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. -
+
Attributes of the JMS <literal><listener-container></literal> element @@ -1210,7 +1214,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem The available configuration options for the JCA variant are described in the following table: -
+
Attributes of the JMS <literal><jca-listener-container/></literal> element diff --git a/src/reference/docbook/jmx.xml b/src/reference/docbook/jmx.xml index 891fd5bc22..85ae5d0d27 100644 --- a/src/reference/docbook/jmx.xml +++ b/src/reference/docbook/jmx.xml @@ -1,11 +1,15 @@ - + 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"> JMX -
+
Introduction The JMX support in Spring provides you with the features to easily @@ -53,7 +57,7 @@ features.
-
+
Exporting your beans to JMX 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 { - ]]><!-- this bean must not be lazily initialized if the exporting is to happen --><!-- this bean must not be lazily initialized if the exporting is to happen --> lazy-init="false" @@ -137,7 +141,7 @@ public class JmxTestBean implements IJmxTestBean { inherited from the Object class) are exposed as operations. -
+
Creating an <interfacename>MBeanServer</interfacename> The above configuration assumes that the application is running in @@ -167,7 +171,7 @@ public class JmxTestBean implements IJmxTestBean { ]]><!-- this bean needs to be eagerly pre-instantiated in order for the exporting to occur; - this means that it must not be marked as lazily initialized + this means that it must not be marked as lazily initialized --> @@ -195,7 +199,7 @@ public class JmxTestBean implements IJmxTestBean { you must (of course) have a JMX implementation on your classpath.
-
+
Reusing an existing <interfacename>MBeanServer</interfacename> If no server is specified, the MBeanExporter @@ -210,10 +214,10 @@ public class JmxTestBean implements IJmxTestBean { ]]><!-- indicate to first look for a server --> - ]]><!-- search for the MBeanServer instance with the given agentId --><!-- search for the MBeanServer instance with the given agentId -->]]> - + ... @@ -227,17 +231,17 @@ public class JmxTestBean implements IJmxTestBean { - ]]><!-- Custom MBeanServerLocator --><!-- Custom MBeanServerLocator --> - + ]]><!-- other beans here --> ]]>
-
+
Lazy-initialized MBeans 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.
-
+
Automatic registration of MBeans Any beans that are exported through the @@ -272,7 +276,7 @@ public class JmxTestBean implements IJmxTestBean { behavior can be overridden as detailed in .
-
+
Controlling the registration behavior Consider the scenario where a Spring @@ -294,7 +298,7 @@ public class JmxTestBean implements IJmxTestBean { ObjectName; these registration behaviors are summarized on the following table: -
+
Registration Behaviors @@ -390,7 +394,7 @@ public class JmxTestBean implements IJmxTestBean { -
+
Controlling the management interface of your beans 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. -
+
The <interfacename>MBeanInfoAssembler</interfacename> Interface @@ -420,7 +424,7 @@ public class JmxTestBean implements IJmxTestBean { source-level metadata or any arbitrary interface.
-
+
Using Source-Level Metadata (JDK 5.0 annotations) Using the MetadataMBeanInfoAssembler you @@ -443,7 +447,7 @@ public class JmxTestBean implements IJmxTestBean { setter to create a write-only or read-only attribute respectively. - The example below shows the annotated version of the + The example below shows the annotated version of the JmxTestBean class that you saw earlier: - ]]><!-- will pick up the ObjectName from the annotation --><!-- will pick up the ObjectName from the annotation --> @@ -548,7 +552,7 @@ public class AnnotationTestBean implements IJmxTestBean { ]]> - + Here you can see that an MetadataMBeanInfoAssembler bean has been @@ -559,13 +563,13 @@ public class AnnotationTestBean implements IJmxTestBean { management interfaces for your Spring-exposed MBeans.
-
+
Source-Level Metadata Types The following source level metadata types are available for use in Spring JMX: -
+
Source-Level Metadata Types @@ -627,7 +631,7 @@ public class AnnotationTestBean implements IJmxTestBean { The following configuration parameters are available for use on these source-level metadata types: -
+
Source-Level Metadata Parameters @@ -763,7 +767,7 @@ public class AnnotationTestBean implements IJmxTestBean {
-
+
The <classname>AutodetectCapableMBeanInfoAssembler</classname> interface @@ -787,7 +791,7 @@ public class AnnotationTestBean implements IJmxTestBean { - ]]><!-- notice how no 'beans' are explicitly configured here --><!-- notice how no 'beans' are explicitly configured here --> @@ -817,7 +821,7 @@ public class AnnotationTestBean implements IJmxTestBean { .
-
+
Defining management interfaces using Java interfaces In addition to the @@ -908,7 +912,7 @@ public class AnnotationTestBean implements IJmxTestBean { create the management interface.
-
+
Using <classname>MethodNameBasedMBeanInfoAssembler</classname> @@ -944,7 +948,7 @@ public class AnnotationTestBean implements IJmxTestBean {
-
+
Controlling the <classname>ObjectName</classname>s for your beans Behind the scenes, the MBeanExporter @@ -966,7 +970,7 @@ public class AnnotationTestBean implements IJmxTestBean { and the MetadataNamingStrategy that uses source level metadata to obtain the ObjectName. -
+
Reading <classname>ObjectName</classname>s from <classname>Properties</classname> You can configure your own @@ -1026,7 +1030,7 @@ public class AnnotationTestBean implements IJmxTestBean { ObjectName.
-
+
Using the <classname>MetadataNamingStrategy</classname> The MetadataNamingStrategy uses @@ -1074,7 +1078,7 @@ public class AnnotationTestBean implements IJmxTestBean {
-
+
Configuring annotation based MBean export If you prefer using the annotation based approach to define your management interfaces, then a convenience subclass of @@ -1129,7 +1133,7 @@ ContextConfiguration {
-
+
JSR-160 Connectors For remote access, Spring JMX module offers two @@ -1137,7 +1141,7 @@ ContextConfiguration { org.springframework.jmx.support package for creating both server- and client-side connectors. -
+
Server-side Connectors To have Spring JMX create, start and expose a JSR-160 @@ -1164,7 +1168,7 @@ ContextConfiguration { - ]]> @@ -1179,7 +1183,7 @@ ContextConfiguration { - @@ -1202,7 +1206,7 @@ ContextConfiguration { ]]>
-
+
Client-side Connectors To create an MBeanServerConnection to a @@ -1215,15 +1219,15 @@ ContextConfiguration { ]]>
-
+
JMX over Burlap/Hessian/SOAP 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 MX4J) you can take advantage + JMX implementations (such as MX4J) you can take advantage of protocols like SOAP, Hessian, Burlap over simple HTTP or SSL and others: @@ -1237,7 +1241,7 @@ ContextConfiguration {
-
+
Accessing MBeans via Proxies Spring JMX allows you to create proxies that re-route calls to @@ -1290,13 +1294,13 @@ ContextConfiguration { MBeanServerConnection.
-
+
Notifications Spring's JMX offering includes comprehensive support for JMX notifications. -
+
Registering Listeners for Notifications 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 MBeanExporter and MBeans registered via some other mechanism). By way of an example, consider the scenario where one - would like to be informed (via a Notification) - each and every time an attribute of a target MBean changes. + would like to be informed (via a Notification) + each and every time an attribute of a target MBean changes. ]]> - With the above configuration in place, every time a JMX - Notification is broadcast from the target MBean - (bean:name=testBean1), the - ConsoleLoggingNotificationListener bean that was - registered as a listener via the - notificationListenerMappings property will be - notified. The ConsoleLoggingNotificationListener - bean can then take whatever action it deems appropriate in response to - the Notification. + With the above configuration in place, every time a JMX + Notification is broadcast from the target MBean + (bean:name=testBean1), the + ConsoleLoggingNotificationListener bean that was + registered as a listener via the + notificationListenerMappings property will be + notified. The ConsoleLoggingNotificationListener + bean can then take whatever action it deems appropriate in response to + the Notification. - You can also use straight bean names as the link between exported beans - and listeners: + You can also use straight bean names as the link between exported beans + and listeners: - + @@ -1388,13 +1392,13 @@ public class ConsoleLoggingNotificationListener ]]> - If one wants to register a single NotificationListener - instance for all of the beans that the enclosing MBeanExporter - is exporting, one can use the special wildcard '*' (sans quotes) - as the key for an entry in the notificationListenerMappings - property map; for example: + If one wants to register a single NotificationListener + instance for all of the beans that the enclosing MBeanExporter + is exporting, one can use the special wildcard '*' (sans quotes) + as the key for an entry in the notificationListenerMappings + property map; for example: - + @@ -1494,7 +1498,7 @@ public class ConsoleLoggingNotificationListener - + ]]><!-- implements both the NotificationListener and NotificationFilter interfaces --> @@ -1511,7 +1515,7 @@ public class ConsoleLoggingNotificationListener ]]>
-
+
Publishing Notifications Spring provides support not just for registering to receive @@ -1568,7 +1572,7 @@ public class ConsoleLoggingNotificationListener add(int, int) operation is invoked. The NotificationPublisher 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 NotificationPublisher and you can accept the coupling to both Spring - and JMX, then do so. + and JMX, then do so.
-
+
Further Resources This section contains links to further resources about JMX. - The JMX homepage at Sun + The JMX homepage at Sun - The JMX specification (JSR-000003) + The JMX specification (JSR-000003) - The JMX Remote API specification (JSR-000160) + The JMX Remote API specification (JSR-000160) - The MX4J - homepage (an Open Source implementation of various JMX + The MX4J + homepage (an Open Source implementation of various JMX specs) - Getting Started with JMX - an introductory article from Sun. + Getting Started with JMX - an introductory article from Sun.
diff --git a/src/reference/docbook/mail.xml b/src/reference/docbook/mail.xml index cb28b3b2bb..271ab42dba 100644 --- a/src/reference/docbook/mail.xml +++ b/src/reference/docbook/mail.xml @@ -1,66 +1,70 @@ - + 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"> Email -
+
Introduction - - Library dependencies - 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. - - - The JavaMail mail.jar library - - - The JAF activation.jar library - - - All of these libraries are freely available on the web. - + + Library dependencies + 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. + + + The JavaMail mail.jar library + + + The JAF activation.jar library + + + All of these libraries are freely available on the web. + 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. - + The org.springframework.mail package is the root level package - for the Spring Framework's email support. The central interface for sending - emails is the MailSender interface; a simple value object - encapsulating the properties of a simple mail such as from and - to (plus many others) is the SimpleMailMessage class. + for the Spring Framework's email support. The central interface for sending + emails is the MailSender interface; a simple value object + encapsulating the properties of a simple mail such as from and + to (plus many others) is the SimpleMailMessage 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 MailException. Please refer to the JavaDocs for more information on the rich mail exception hierarchy. The org.springframework.mail.javamail.JavaMailSender - interface adds specialized JavaMail features such as MIME + interface adds specialized JavaMail features such as MIME message support to the MailSender interface - (from which it inherits). JavaMailSender also provides a - callback interface for preparation of JavaMail MIME messages, called + (from which it inherits). JavaMailSender also provides a + callback interface for preparation of JavaMail MIME messages, called org.springframework.mail.javamail.MimeMessagePreparator
-
- Usage - Let's assume there is a business interface called OrderManager: - + Usage + Let's assume there is a business interface called OrderManager: + - 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. - -
- Basic <interfacename>MailSender</interfacename> and <classname>SimpleMailMessage</classname> usage - 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. + +
+ Basic <interfacename>MailSender</interfacename> and <classname>SimpleMailMessage</classname> usage + // simply log it and go on... - - Find below the bean definitions for the above code: - + + Find below the bean definitions for the above code: + @@ -117,17 +121,17 @@ public class SimpleOrderManager implements OrderManager { ]]> -
- -
- Using the <interfacename>JavaMailSender</interfacename> and the <classname>MimeMessagePreparator</classname> - Here is another implementation of OrderManager using - the MimeMessagePreparator callback interface. Please note - in this case that the mailSender property is of type - JavaMailSender so that we are able to use the JavaMail - MimeMessage class: - - + +
+ Using the <interfacename>JavaMailSender</interfacename> and the <classname>MimeMessagePreparator</classname> + Here is another implementation of OrderManager using + the MimeMessagePreparator callback interface. Please note + in this case that the mailSender property is of type + JavaMailSender so that we are able to use the JavaMail + MimeMessage class: + + // Do the business calculations...// Call the collaborators to persist the order...// simply log it and go on... - - - The mail code is a crosscutting concern and could well be a candidate - for refactoring into a custom Spring AOP aspect, - which then could be executed at appropriate joinpoints on the - OrderManager target. - - - The Spring Framework's mail support ships with the standard JavaMail - implementation. Please refer to the relevant JavaDocs for more information. -
- -
- -
- Using the JavaMail <classname>MimeMessageHelper</classname> - - A class that comes in pretty handy when dealing with JavaMail messages is - the org.springframework.mail.javamail.MimeMessageHelper class, - which shields you from having to use the verbose JavaMail API. Using - the MimeMessageHelper it is pretty easy to - create a MimeMessage: - // of course you would use DI in any real-world cases + The mail code is a crosscutting concern and could well be a candidate + for refactoring into a custom Spring AOP aspect, + which then could be executed at appropriate joinpoints on the + OrderManager target. + + + The Spring Framework's mail support ships with the standard JavaMail + implementation. Please refer to the relevant JavaDocs for more information. +
+ +
+ +
+ Using the JavaMail <classname>MimeMessageHelper</classname> + + A class that comes in pretty handy when dealing with JavaMail messages is + the org.springframework.mail.javamail.MimeMessageHelper class, + which shields you from having to use the verbose JavaMail API. Using + the MimeMessageHelper it is pretty easy to + create a MimeMessage: + // of course you would use DI in any real-world cases - -
- Sending attachments and inline resources - 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. -
- Attachments - The following example shows you how to use the - MimeMessageHelper to send an email along with a - single JPEG image attachment. - + Sending attachments and inline resources + 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. +
+ Attachments + The following example shows you how to use the + MimeMessageHelper to send an email along with a + single JPEG image attachment. + -
-
- Inline resources - The following example shows you how to use the - MimeMessageHelper to send an email along with an - inline image. - +
+ Inline resources + The following example shows you how to use the + MimeMessageHelper to send an email along with an + inline image. + - - Inline resources are added to the mime message using the - specified Content-ID (identifier1234 - in the above example). The order in which you are adding the text and the - resource are very important. Be sure to - first add the text and after that the resources. If - you are doing it the other way around, it won't work! - -
-
-
- Creating email content using a templating library - The code in the previous examples explicitly created the - content of the email message, using methods calls such as - message.setText(..). 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. - 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. - - - - Creating HTML-based email content in Java code is tedious and error prone - - - There is no clear separation between display logic and business logic - - - Changing the display structure of the email content requires writing Java code, recompiling, redeploying... - - - - 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. -
- A Velocity-based example - To use Velocity 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. - # in the com/foo/package + Inline resources are added to the mime message using the + specified Content-ID (identifier1234 + in the above example). The order in which you are adding the text and the + resource are very important. Be sure to + first add the text and after that the resources. If + you are doing it the other way around, it won't work! + +
+
+
+ Creating email content using a templating library + The code in the previous examples explicitly created the + content of the email message, using methods calls such as + message.setText(..). 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. + 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. + + + + Creating HTML-based email content in Java code is tedious and error prone + + + There is no clear separation between display logic and business logic + + + Changing the display structure of the email content requires writing Java code, recompiling, redeploying... + + + + 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. +
+ A Velocity-based example + To use Velocity 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. + # in the com/foo/package

Hi ${user.userName}, welcome to the Chipping Sodbury On-the-Hill message boards!

@@ -317,10 +321,10 @@ sender.send(message);]]>
]]> - 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). - 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). + - + - + @@ -393,8 +397,8 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans ]]> -
-
-
- +
+
+
+ diff --git a/src/reference/docbook/mvc.xml b/src/reference/docbook/mvc.xml index 6b82097854..37d0a27c4a 100644 --- a/src/reference/docbook/mvc.xml +++ b/src/reference/docbook/mvc.xml @@ -1,11 +1,15 @@ - + 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"> Web MVC framework -
+
Introduction to Spring Web MVC framework The Spring Web model-view-controller (MVC) framework is designed @@ -20,7 +24,7 @@ @PathVariable annotation and other features. - + <quote>Open for extension...</quote> A key design principle in Spring Web MVC and in Spring in general @@ -39,9 +43,9 @@ - Bob - Martin, The Open-Closed Principle (PDF) + Bob + Martin, The Open-Closed Principle (PDF) @@ -79,7 +83,7 @@ transformed into an appropriate format, such as JSP request attributes, a Velocity template model. -
+
Features of Spring Web MVC<!--I moved Features of Spring Web MVC before Pluggability of other MVC implementations. You want to highlight your own imp. first.--> @@ -179,7 +183,7 @@
-
+
Pluggability of other MVC implementations Non-Spring MVC implementations are preferable for some projects. @@ -212,7 +216,7 @@
-
+
The <classname>DispatcherServlet</classname> Spring's web MVC framework is, like many other web MVC frameworks, @@ -285,7 +289,7 @@ registration.setLoadOnStartup(1); registration.addMapping("/example/*"); } - + } WebApplicationInitializer is an interface @@ -376,295 +380,295 @@ look up the WebApplicationContext if you need access to it. -
- Special Bean Types In the <interfacename>WebApplicationContext</interfacename> +
+ Special Bean Types In the <interfacename>WebApplicationContext</interfacename> - The Spring DispatcherServlet uses special - beans to process requests and render the appropriate views. These beans - are part of Spring MVC. You can choose which special beans to use - by simply configuring one or more of them in the - WebApplicationContext. - However, you don't need to do that initially since Spring MVC - maintains a list of default beans to use if you don't configure any. - More on that in the next section. First see the table below - listing the special bean types the - DispatcherServlet relies on. - - - Special bean types in the - <interfacename>WebApplicationContext</interfacename> - - - - - - - - - Bean type - - Explanation - - - - - - HandlerMapping - - Maps incoming requests to handlers and a list of - pre- and post-processors (handler interceptors) based on some - criteria the details of which vary by HandlerMapping - implementation. The most popular implementation supports - annotated controllers but other implementations exists as well. - - - - HandlerAdapter - - Helps the DispatcherServlet to - invoke a handler mapped to a request regardless of the handler - is actually invoked. For example, invoking an annotated controller - requires resolving various annotations. Thus the main purpose - of a HandlerAdapter is to shield the - DispatcherServlet from such details. - - - - HandlerExceptionResolver - - Maps exceptions to views also allowing for more - complex exception handling code. - - - - ViewResolver - - Resolves logical String-based view names to actual - View types. - - - - LocaleResolver - - Resolves the locale a client is using, - in order to be able to offer internationalized views - - - - ThemeResolver - - Resolves themes your web application can use, for - example, to offer personalized layouts - - - - MultipartResolver - - Parses multi-part requests for example to support processing - file uploads from HTML forms. - - - - FlashMapManager - - Stores and retrieves the "input" and the "output" - FlashMap that can be used to pass attributes - from one request to another, usually across a redirect. - - - -
- -
+ The Spring DispatcherServlet uses special + beans to process requests and render the appropriate views. These beans + are part of Spring MVC. You can choose which special beans to use + by simply configuring one or more of them in the + WebApplicationContext. + However, you don't need to do that initially since Spring MVC + maintains a list of default beans to use if you don't configure any. + More on that in the next section. First see the table below + listing the special bean types the + DispatcherServlet relies on. -
- Default DispatcherServlet Configuration - - As mentioned in the previous section for each special bean - the DispatcherServlet maintains a list - of implementations to use by default. This information is - kept in the file DispatcherServlet.properties - in the package org.springframework.web.servlet. - - - All special beans have some reasonable defaults of - their own. Sooner or later though you'll need to customize - one or more of the properties these beans provide. - For example it's quite common to configure - an InternalResourceViewResolver - settings its prefix property to - the parent location of view files. - - Regardless of the details, the important concept - to understand here is that once - you configure a special bean such as an - InternalResourceViewResolver - in your WebApplicationContext, you - effectively override the list of default implementations - that would have been used otherwise for that special bean - type. For example if you configure an - InternalResourceViewResolver, - the default list of ViewResolver - implementations is ignored. - - - In you'll learn about - other options for configuring Spring MVC including - MVC Java config and the MVC XML namespace both of which provide - a simple starting point and assume little knowledge of - how Spring MVC works. Regardless of how you choose to - configure your application, the concepts explained in this - section are fundamental should be of help to you. - - -
+ + Special bean types in the + <interfacename>WebApplicationContext</interfacename> -
- DispatcherServlet Processing Sequence + + - After you set up a DispatcherServlet, and a - request comes in for that specific - DispatcherServlet, the - DispatcherServlet starts processing the request as - follows: - - - - The WebApplicationContext is - searched for and bound in the request as an attribute that the - controller and other elements in the process can use. It - is bound by default under the key - DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE. - - - - The locale resolver is bound to the request to enable elements - in the process to resolve the locale to use when processing the - request (rendering the view, preparing data, and so on). If you do not - need locale resolving, you do not need it. - - - - - - The theme resolver is bound to the request to let elements such - as views determine which theme to use. If you do not use themes, you - can ignore it. - - - - - - - - If you specify a multipart file resolver, the request is - inspected for multiparts; if multiparts are found, the request is - wrapped in a MultipartHttpServletRequest for - further processing by other elements in the process. See for further information about multipart - handling. - - - - An appropriate handler is searched for. If a handler is found, - the execution chain associated with the handler (preprocessors, - postprocessors, and controllers) is executed in order to prepare a - model or rendering. - - - - If a model is returned, the view is rendered. If no model is - returned, (may be due to a preprocessor or postprocessor intercepting - the request, perhaps for security reasons), no view is rendered, - because the request could already have been fulfilled. - - - - - - Handler exception resolvers that are declared in the - WebApplicationContext pick up exceptions - that are thrown during processing of the request. Using these exception - resolvers allows you to define custom behaviors to address - exceptions. - -
+ - The Spring DispatcherServlet also supports - the return of the last-modification-date, as - specified by the Servlet API. The process of determining the last - modification date for a specific request is straightforward: the - DispatcherServlet looks up an appropriate handler - mapping and tests whether the handler that is found implements the - LastModified - interface. If so, the value of the long - getLastModified(request) method of the - LastModified interface is returned to the - client. + + + Bean type - You can customize individual - DispatcherServlet instances by adding Servlet - initialization parameters (init-param elements) to the - Servlet declaration in the web.xml file. See the - following table for the list of supported parameters. + Explanation + + - + + + HandlerMapping - + Maps incoming requests to handlers and a list of + pre- and post-processors (handler interceptors) based on some + criteria the details of which vary by HandlerMapping + implementation. The most popular implementation supports + annotated controllers but other implementations exists as well. + -
- <classname>DispatcherServlet</classname> initialization - parameters + + HandlerAdapter - - + Helps the DispatcherServlet to + invoke a handler mapped to a request regardless of the handler + is actually invoked. For example, invoking an annotated controller + requires resolving various annotations. Thus the main purpose + of a HandlerAdapter is to shield the + DispatcherServlet from such details. + - + + HandlerExceptionResolver - - - Parameter + Maps exceptions to views also allowing for more + complex exception handling code. + - Explanation - - + + ViewResolver - - - contextClass + Resolves logical String-based view names to actual + View types. + - Class that implements - WebApplicationContext, which - instantiates the context used by this Servlet. By default, the - XmlWebApplicationContext is used. - + + LocaleResolver - - contextConfigLocation + Resolves the locale a client is using, + in order to be able to offer internationalized views + - String that is passed to the context instance (specified by - contextClass) to indicate where context(s) can - be found. The string consists potentially of multiple strings - (using a comma as a delimiter) to support multiple contexts. In - case of multiple context locations with beans that are defined - twice, the latest location takes precedence. + + ThemeResolver - - + Resolves themes your web application can use, for + example, to offer personalized layouts + - - namespace + + MultipartResolver - Namespace of the - WebApplicationContext. Defaults to - [servlet-name]-servlet. - - - -
+ Parses multi-part requests for example to support processing + file uploads from HTML forms. + + + + FlashMapManager + + Stores and retrieves the "input" and the "output" + FlashMap that can be used to pass attributes + from one request to another, usually across a redirect. + + + + + +
+ +
+ Default DispatcherServlet Configuration + + As mentioned in the previous section for each special bean + the DispatcherServlet maintains a list + of implementations to use by default. This information is + kept in the file DispatcherServlet.properties + in the package org.springframework.web.servlet. + + + All special beans have some reasonable defaults of + their own. Sooner or later though you'll need to customize + one or more of the properties these beans provide. + For example it's quite common to configure + an InternalResourceViewResolver + settings its prefix property to + the parent location of view files. + + Regardless of the details, the important concept + to understand here is that once + you configure a special bean such as an + InternalResourceViewResolver + in your WebApplicationContext, you + effectively override the list of default implementations + that would have been used otherwise for that special bean + type. For example if you configure an + InternalResourceViewResolver, + the default list of ViewResolver + implementations is ignored. + + + In you'll learn about + other options for configuring Spring MVC including + MVC Java config and the MVC XML namespace both of which provide + a simple starting point and assume little knowledge of + how Spring MVC works. Regardless of how you choose to + configure your application, the concepts explained in this + section are fundamental should be of help to you. + + +
+ +
+ DispatcherServlet Processing Sequence + + After you set up a DispatcherServlet, and a + request comes in for that specific + DispatcherServlet, the + DispatcherServlet starts processing the request as + follows: + + + + The WebApplicationContext is + searched for and bound in the request as an attribute that the + controller and other elements in the process can use. It + is bound by default under the key + DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE. + + + + The locale resolver is bound to the request to enable elements + in the process to resolve the locale to use when processing the + request (rendering the view, preparing data, and so on). If you do not + need locale resolving, you do not need it. + + + + + + The theme resolver is bound to the request to let elements such + as views determine which theme to use. If you do not use themes, you + can ignore it. + + + + + + + + If you specify a multipart file resolver, the request is + inspected for multiparts; if multiparts are found, the request is + wrapped in a MultipartHttpServletRequest for + further processing by other elements in the process. See for further information about multipart + handling. + + + + An appropriate handler is searched for. If a handler is found, + the execution chain associated with the handler (preprocessors, + postprocessors, and controllers) is executed in order to prepare a + model or rendering. + + + + If a model is returned, the view is rendered. If no model is + returned, (may be due to a preprocessor or postprocessor intercepting + the request, perhaps for security reasons), no view is rendered, + because the request could already have been fulfilled. + + + + + + Handler exception resolvers that are declared in the + WebApplicationContext pick up exceptions + that are thrown during processing of the request. Using these exception + resolvers allows you to define custom behaviors to address + exceptions. + + + The Spring DispatcherServlet also supports + the return of the last-modification-date, as + specified by the Servlet API. The process of determining the last + modification date for a specific request is straightforward: the + DispatcherServlet looks up an appropriate handler + mapping and tests whether the handler that is found implements the + LastModified + interface. If so, the value of the long + getLastModified(request) method of the + LastModified interface is returned to the + client. + + You can customize individual + DispatcherServlet instances by adding Servlet + initialization parameters (init-param elements) to the + Servlet declaration in the web.xml file. See the + following table for the list of supported parameters. + + + + + + + <classname>DispatcherServlet</classname> initialization + parameters + + + + + + + + + Parameter + + Explanation + + + + + + contextClass + + Class that implements + WebApplicationContext, which + instantiates the context used by this Servlet. By default, the + XmlWebApplicationContext is used. + + + + contextConfigLocation + + String that is passed to the context instance (specified by + contextClass) to indicate where context(s) can + be found. The string consists potentially of multiple strings + (using a comma as a delimiter) to support multiple contexts. In + case of multiple context locations with beans that are defined + twice, the latest location takes precedence. + + + + + + namespace + + Namespace of the + WebApplicationContext. Defaults to + [servlet-name]-servlet. + + + +
+
-
+
Implementing Controllers Controllers provide access to the application behavior that you @@ -719,7 +723,7 @@ public class HelloWorldController { documents these annotations and how they are most commonly used in a Servlet environment. -
+
Defining a controller with <interfacename>@Controller</interfacename> @@ -750,14 +754,14 @@ public class HelloWorldController { snippet: <?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" - xmlns:p="http://www.springframework.org/schema/p" + xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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/context + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="org.springframework.samples.petclinic.web"/> @@ -767,7 +771,7 @@ public class HelloWorldController { </beans>
-
+
Mapping Requests With <interfacename>@RequestMapping</interfacename> @@ -788,7 +792,7 @@ public class HelloWorldController { public class AppointmentsController { private final AppointmentBook appointmentBook; - + @Autowired public AppointmentsController(AppointmentBook appointmentBook) { this.appointmentBook = appointmentBook; @@ -885,7 +889,7 @@ public class ClinicController { mechanisms see . -
+
New Support Classes for <classname>@RequestMapping</classname> methods in Spring MVC 3.1 Spring 3.1 introduced a new set of support classes for @@ -948,7 +952,7 @@ public class ClinicController {
-
+
URI Template Patterns URI templates can be used for convenient @@ -957,9 +961,9 @@ public class ClinicController { A URI Template is a URI-like string, containing one or more variable names. When you substitute values for these variables, the - template becomes a URI. The proposed - RFC for URI Templates defines how a URI is parameterized. For + template becomes a URI. The proposed + RFC for URI Templates defines how a URI is parameterized. For example, the URI Template http://www.example.com/users/{userId} contains the variable userId. Assigning the value @@ -972,9 +976,9 @@ public class ClinicController { @RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET) public String findOwner(@PathVariable String ownerId, Model model) { - Owner owner = ownerService.findOwner(ownerId); - model.addAttribute("owner", owner); - return "displayOwner"; + Owner owner = ownerService.findOwner(ownerId); + model.addAttribute("owner", owner); + return "displayOwner"; } The URI Template "/owners/{ownerId}" @@ -1012,10 +1016,10 @@ public String findOwner(@PathVariable String ow @RequestMapping(value="/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET) public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { - Owner owner = ownerService.findOwner(ownerId); - Pet pet = owner.getPet(petId); - model.addAttribute("pet", pet); - return "displayPet"; + Owner owner = ownerService.findOwner(ownerId); + Pet pet = owner.getPet(petId); + model.addAttribute("pet", pet); + return "displayPet"; } When a @PathVariable annotation is @@ -1033,7 +1037,7 @@ public String findPet(@PathVariable String owne public class RelativePathUriTemplateController { @RequestMapping("/pets/{petId}") - public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { + public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } } @@ -1047,7 +1051,7 @@ public class RelativePathUriTemplateController { linkend="mvc-ann-webdatabinder" />.
-
+
URI Template Patterns with Regular Expressions Sometimes you need more precision in defining URI template @@ -1063,13 +1067,13 @@ public class RelativePathUriTemplateController { @RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}") - public void handle(@PathVariable String version, @PathVariable String extension) { + public void handle(@PathVariable String version, @PathVariable String extension) { // ... } }
-
+
Path Patterns In addition to URI templates, the @@ -1080,15 +1084,15 @@ public class RelativePathUriTemplateController { /owners/*/pets/{petId}).
-
+
Matrix Variables The URI specification - RFC 3986 + RFC 3986 defines the possibility of including name-value pairs within path segments. There is no specific term used in the spec. The general "URI path parameters" could be applied although the more unique - "Matrix URIs", + "Matrix URIs", originating from an old post by Tim Berners-Lee, is also frequently used and fairly well known. Within Spring MVC these are referred to as matrix variables. @@ -1111,7 +1115,7 @@ public class RelativePathUriTemplateController { // GET /pets/42;q=11;r=22 @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET) -public void findPet(@PathVariable String petId, @MatrixVariable int q) { +public void findPet(@PathVariable String petId, @MatrixVariable int q) { // petId == 42 // q == 11 @@ -1119,15 +1123,15 @@ public void findPet(@PathVariable String petId, @MatrixVariable int q) { } Since all path segments may contain matrix variables, in some cases - you need to be more specific to identify where the variable is expected to be: + you need to be more specific to identify where the variable is expected to be: // GET /owners/42;q=11/pets/21;q=22 @RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET) public void findPet( @MatrixVariable(value="q", pathVar="ownerId") int q1, - @MatrixVariable(value="q", pathVar="petId") int q2) { - + @MatrixVariable(value="q", pathVar="petId") int q2) { + // q1 == 11 // q2 == 22 @@ -1138,7 +1142,7 @@ public void findPet( // GET /pets/42 @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET) - public void findPet(@MatrixVariable(required=true, defaultValue="1") int q) { + public void findPet(@MatrixVariable(required=true, defaultValue="1") int q) { // q == 1 @@ -1151,7 +1155,7 @@ public void findPet( @RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET) public void findPet( @MatrixVariable Map<String, String> matrixVars, - @MatrixVariable(pathVar="petId"") Map<String, String> petMatrixVars) { + @MatrixVariable(pathVar="petId"") Map<String, String> petMatrixVars) { // matrixVars: ["q" : [11,22], "r" : 12, "s" : 23] // petMatrixVars: ["q" : 11, "s" : 23] @@ -1167,7 +1171,7 @@ public void findPet(
-
+
Consumable Media Types You can narrow the primary mapping by specifying a list of @@ -1178,7 +1182,7 @@ public void findPet( @Controller @RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json") -public void addPet(@RequestBody Pet pet, Model model) { +public void addPet(@RequestBody Pet pet, Model model) { // implementation omitted } @@ -1195,7 +1199,7 @@ public void addPet(@RequestBody Pet pet, Model model) {
-
+
Producible Media Types You can narrow the primary mapping by specifying a list of @@ -1210,7 +1214,7 @@ public void addPet(@RequestBody Pet pet, Model model) { @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json") @ResponseBody -public Pet getPet(@PathVariable String petId, Model model) { +public Pet getPet(@PathVariable String petId, Model model) { // implementation omitted } @@ -1228,7 +1232,7 @@ public Pet getPet(@PathVariable String petId, Model model) {
-
+
Request Parameters and Header Values You can narrow request matching through request parameter @@ -1244,7 +1248,7 @@ public class RelativePathUriTemplateController { @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue") - public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { + public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } } @@ -1258,7 +1262,7 @@ public class RelativePathUriTemplateController { @RequestMapping(value = "/pets", method = RequestMethod.GET, headers="myHeader=myValue") - public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { + public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } } @@ -1276,8 +1280,8 @@ public class RelativePathUriTemplateController {
-
- Defining <interface>@RequestMapping</interface> handler + <section xml:id="mvc-ann-methods"> + <title>Defining <interfacename>@RequestMapping</interfacename> handler methods An @RequestMapping handler method can have @@ -1298,7 +1302,7 @@ public class RelativePathUriTemplateController { configured explicitly if using neither. -
+
Supported method argument types The following are the supported method arguments: @@ -1462,11 +1466,11 @@ public class RelativePathUriTemplateController { indicated by the @SessionAttributes annotation at the handler type level. - + org.springframework.web.util.UriComponentsBuilder - a builder for preparing a URL relative to the current request's - host, port, scheme, context path, and the literal part of the + a builder for preparing a URL relative to the current request's + host, port, scheme, context path, and the literal part of the servlet mapping. @@ -1496,7 +1500,7 @@ public String processSubmit(@ModelAttribute("pet") Pet pet
-
+
Supported method return types The following are the supported return types: @@ -1586,7 +1590,7 @@ public String processSubmit(@ModelAttribute("pet") Pet pet
-
+
Binding request parameters to method parameters with <interfacename>@RequestParam</interfacename> @@ -1623,7 +1627,7 @@ public class EditPetForm { linkend="mvc-ann-typeconversion" />.
-
+
Mapping the request body with the @RequestBody annotation @@ -1693,10 +1697,10 @@ public void handle(@RequestBody String body, Writer writer) throws IOException { </property </bean> -<bean id="stringHttpMessageConverter" +<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/> -<bean id="marshallingHttpMessageConverter" +<bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="marshaller" ref="castorMarshaller" /> <property name="unmarshaller" ref="castorMarshaller" /> @@ -1726,7 +1730,7 @@ public void handle(@RequestBody String body, Writer writer) throws IOException {
-
+
Mapping the response body with the <interfacename>@ResponseBody</interfacename> annotation @@ -1752,7 +1756,7 @@ public String helloWorld() { linkend="rest-message-conversion">Message Converters.
-
+
Using <classname>HttpEntity<?></classname> The HttpEntity is similar to @@ -1788,7 +1792,7 @@ public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntit linkend="rest-message-conversion">Message Converters.
-
+
Using <interfacename>@ModelAttribute</interfacename> on a method @@ -1872,7 +1876,7 @@ public void populateModel(@RequestParam String number, Model model) { returning void — see .
-
+
Using <interfacename>@ModelAttribute</interfacename> on a method argument @@ -1893,7 +1897,7 @@ public void populateModel(@RequestParam String number, Model model) { @RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@ModelAttribute Pet pet) { - + } Given the above example where can the Pet instance come from? @@ -1962,12 +1966,12 @@ public String save(@ModelAttribute("account") Account account) { @RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { - + if (result.hasErrors()) { return "petForm"; - } - - // ... + } + + // ... } @@ -1991,7 +1995,7 @@ public String processSubmit(@ModelAttribute("pet") Pet pet if (result.hasErrors()) { return "petForm"; } - + // ... } @@ -2005,7 +2009,7 @@ public String processSubmit(@Valid @ModelAttribute("pet") if (result.hasErrors()) { return "petForm"; } - + // ... } @@ -2014,7 +2018,7 @@ public String processSubmit(@Valid @ModelAttribute("pet") validation.
-
+
Using <classname>@SessionAttributes</classname> to store model attributes in the HTTP session between requests @@ -2045,7 +2049,7 @@ public class EditPetForm {
-
+
Specifying redirect and flash attributes By default all model attributes are considered to be exposed as @@ -2090,7 +2094,7 @@ public class EditPetForm { MVC.
-
+
Working with <literal>"application/x-www-form-urlencoded"</literal> data @@ -2134,7 +2138,7 @@ public class EditPetForm { methods.
-
+
Mapping cookie values with the @CookieValue annotation The @CookieValue annotation @@ -2164,7 +2168,7 @@ public void displayHeaderInfo(@CookieValue("JSESSIONID")
-
+
Mapping request header attributes with the @RequestHeader annotation @@ -2211,7 +2215,7 @@ public void displayHeaderInfo(@RequestHeader("Accept-Encod Servlet and Portlet environments.
-
+
Method Parameters And Type Conversion String-based values extracted from the request including request @@ -2230,7 +2234,7 @@ public void displayHeaderInfo(@RequestHeader("Accept-Encod linkend="format" />).
-
+
Customizing <classname>WebDataBinder</classname> initialization @@ -2242,7 +2246,7 @@ public void displayHeaderInfo(@RequestHeader("Accept-Encod or provide a custom WebBindingInitializer. -
+
Customizing data binding with <interfacename>@InitBinder</interfacename> @@ -2283,7 +2287,7 @@ public class MyFormController { }
-
+
Configuring a custom <interfacename>WebBindingInitializer</interfacename> @@ -2309,7 +2313,7 @@ public class MyFormController { </bean>
-
+
Customizing data binding with externalized <interfacename>@InitBinder</interfacename> methods @@ -2326,7 +2330,7 @@ public class MyFormController {
-
+
Support for the 'Last-Modified' Response Header To Facilitate Content Caching @@ -2367,7 +2371,7 @@ public String myHandleMethod(WebRequest webRequest, Model model) {
-
+
Handler mappings In previous versions of Spring, users were required to define one or @@ -2454,7 +2458,7 @@ public String myHandleMethod(WebRequest webRequest, Model model) { <beans> -
+
Intercepting requests with a <interfacename>HandlerInterceptor</interfacename> @@ -2566,7 +2570,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
-
+
Resolving views All MVC frameworks for web applications provide a way to address @@ -2584,7 +2588,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { interface addresses the preparation of the request and hands the request over to one of the view technologies. -
+
Resolving views with the <interfacename>ViewResolver</interfacename> interface @@ -2597,7 +2601,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { with quite a few view resolvers. This table lists most of them; a couple of examples follow. - +
View resolvers @@ -2743,7 +2747,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { -
+
Chaining ViewResolvers Spring supports multiple view resolvers. Thus you can chain @@ -2772,7 +2776,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { <property name="location" value="/WEB-INF/views.xml"/> </bean> -<!-- in views.xml --> +<!-- in views.xml --> <beans> <bean name="report" class="org.springframework.example.ReportExcelView"/> @@ -2802,7 +2806,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { always return a view!
-
+
Redirecting to views<!--Revise to say what you are redirecting to views. OR are you redirecting views? In that case heading should be Redirecting views.--> As mentioned previously, a controller typically returns a logical @@ -2839,7 +2843,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter { refresh forces a GET of the result page, not a resend of the initial POST data. -
+
<classname>RedirectView</classname> One way to force a redirect as the result of a controller @@ -2890,7 +2894,7 @@ public String upload(...) { view names. The next section discusses this process.
-
+
The <literal>redirect:</literal> prefix While the use of RedirectView works fine, @@ -2918,7 +2922,7 @@ public String upload(...) { redirect to an absolute URL.
-
+
The <literal>forward:</literal> prefix<!--Can you revise this heading to say what you're using the forward prefix to accomplish?--> It is also possible to use a special forward: @@ -2942,7 +2946,7 @@ public String upload(...) {
-
+
<classname>ContentNegotiatingViewResolver</classname> The ContentNegotiatingViewResolver does not @@ -2966,16 +2970,16 @@ public String upload(...) { Use the same URI for the client to locate the resource, but set the Accept HTTP request header to list the - media - types that it understands. For example, an HTTP request for + media + types that it understands. For example, an HTTP request for http://www.example.com/users/fred with an Accept header set to application/pdf requests a PDF representation of the user fred, while http://www.example.com/users/fred with an Accept header set to text/xml - requests an XML representation. This strategy is known as content - negotiation. + requests an XML representation. This strategy is known as content + negotiation. @@ -3115,7 +3119,7 @@ public class ContentController {
-
+
Using flash attributes Flash attributes provide a way for one request to store attributes @@ -3150,7 +3154,7 @@ public class ContentController { automatically added to the Model of the controller serving the target URL. - + Matching requests to flash attributes The concept of flash attributes exists in many other Web @@ -3176,77 +3180,77 @@ public class ContentController {
-
+
Building <literal>URI</literal>s Spring MVC provides a mechanism for building and encoding a URI using UriComponentsBuilder and UriComponents. - + For example you can expand and encode a URI template string: -UriComponents uriComponents = +UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build(); - + URI uri = uriComponents.expand("42", "21").encode().toUri(); - Note that UriComponents is immutable and - the expand() and encode() + Note that UriComponents is immutable and + the expand() and encode() operations return new instances if necessary. - + You can also expand and encode using individual URI components: - -UriComponents uriComponents = + +UriComponents uriComponents = UriComponentsBuilder.newInstance() .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build() .expand("42", "21") .encode(); - In a Servlet environment the - ServletUriComponentsBuilder sub-class provides - static factory methods to copy available URL information from a - Servlet requests: - + In a Servlet environment the + ServletUriComponentsBuilder sub-class provides + static factory methods to copy available URL information from a + Servlet requests: + HttpServletRequest request = ... // Re-use host, scheme, port, path and query string // Replace the "accountId" query param -ServletUriComponentsBuilder ucb = +ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromRequest(request).replaceQueryParam("accountId", "{id}").build() .expand("123") .encode(); - Alternatively, you may choose to copy a subset of the available + Alternatively, you may choose to copy a subset of the available information up to and including the context path: // Re-use host, port and context path // Append "/accounts" to the path -ServletUriComponentsBuilder ucb = +ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromContextPath(request).path("/accounts").build() Or in cases where the DispatcherServlet is mapped - by name (e.g. /main/*), you can also have the literal part + by name (e.g. /main/*), you can also have the literal part of the servlet mapping included: // Re-use host, port, context path // Append the literal part of the servlet mapping to the path // Append "/accounts" to the path -ServletUriComponentsBuilder ucb = +ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromServletMapping(request).path("/accounts").build()
-
+
Using locales Most parts of Spring's architecture support internationalization, @@ -3272,7 +3276,7 @@ ServletUriComponentsBuilder ucb = configured in your application context in the normal way. Here is a selection of the locale resolvers included in Spring. -
+
<classname>AcceptHeaderLocaleResolver</classname> This locale resolver inspects the @@ -3281,7 +3285,7 @@ ServletUriComponentsBuilder ucb = the locale of the client's operating system.
-
+ <classname>CookieLocaleResolver</classname> properties @@ -3354,7 +3358,7 @@ ServletUriComponentsBuilder ucb =
-
+
<classname>SessionLocaleResolver</classname> The SessionLocaleResolver allows you to @@ -3362,7 +3366,7 @@ ServletUriComponentsBuilder ucb = user's request.
-
+
<classname>LocaleChangeInterceptor</classname> You can enable changing of locales by adding the @@ -3400,10 +3404,10 @@ ServletUriComponentsBuilder ucb =
-
+
Using themes -
+
Overview of themes You can apply Spring Web MVC framework themes to set the overall @@ -3412,7 +3416,7 @@ ServletUriComponentsBuilder ucb = images, that affect the visual style of the application.
-
+
Defining themes To use themes in your web application, you must set up an @@ -3469,7 +3473,7 @@ background=/themes/cool/img/coolBg.jpg special background image with Dutch text on it.
-
+
Theme resolvers After you define themes, as in the preceding section, you decide @@ -3481,7 +3485,7 @@ background=/themes/cool/img/coolBg.jpg use for a particular request and can also alter the request's theme. The following theme resolvers are provided by Spring: - +
<interfacename>ThemeResolver</interfacename> implementations @@ -3530,10 +3534,10 @@ background=/themes/cool/img/coolBg.jpg -
+
Spring's multipart (file upload) support -
+
Introduction Spring's built-in multipart support handles file uploads in web @@ -3541,9 +3545,9 @@ background=/themes/cool/img/coolBg.jpg MultipartResolver objects, defined in the org.springframework.web.multipart package. Spring provides one MultipartResolver - implementation for use with Commons - FileUpload and another for use with Servlet 3.0 + implementation for use with Commons + FileUpload and another for use with Servlet 3.0 multipart request parsing. By default, Spring does no multipart handling, because some @@ -3557,7 +3561,7 @@ background=/themes/cool/img/coolBg.jpg treated like any other attribute.
-
+
Using a <interfacename>MultipartResolver</interfacename> with <emphasis>Commons FileUpload</emphasis> @@ -3587,7 +3591,7 @@ background=/themes/cool/img/coolBg.jpg get access to the multipart files themselves in your controllers.
-
+
Using a <interfacename>MultipartResolver</interfacename> with <emphasis>Servlet 3.0</emphasis> @@ -3614,7 +3618,7 @@ background=/themes/cool/img/coolBg.jpg </bean>
-
+
Handling a file upload in a form After the MultipartResolver completes its @@ -3648,7 +3652,7 @@ background=/themes/cool/img/coolBg.jpg public class FileUploadController { @RequestMapping(value = "/form", method = RequestMethod.POST) - public String handleFormUpload(@RequestParam("name") String name, + public String handleFormUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { @@ -3681,14 +3685,14 @@ public class FileUploadController { InputStream inputStream = file.getInputStream(); // store bytes from uploaded file somewhere - + return "redirect:uploadSuccess"; } }
-
+
Handling a file upload request from programmatic clients Multipart requests can also be submitted from non-browser clients @@ -3699,12 +3703,12 @@ public class FileUploadController { multipart request with a file and second part with JSON formatted data: POST /someUrl Content-Type: multipart/mixed - + --edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp Content-Disposition: form-data; name="meta-data" Content-Type: application/json; charset=UTF-8 Content-Transfer-Encoding: 8bit - + { "name": "value" } @@ -3747,12 +3751,12 @@ public String onSubmit(@RequestPart("meta-data") MetaData
-
+
Handling exceptions -
+
<interfacename>HandlerExceptionResolver</interfacename> + xml:id="mvc-HandlerExceptionResolver">HandlerExceptionResolver Spring HandlerExceptionResolver implementations deal with unexpected exceptions that occur during controller execution. @@ -3787,7 +3791,7 @@ public String onSubmit(@RequestPart("meta-data") MetaData The following sections explain this in more detail.
-
+
<interfacename>@ExceptionHandler</interfacename> The HandlerExceptionResolver interface @@ -3854,7 +3858,7 @@ public class SimpleController {
-
+
Handling Standard Spring MVC Exceptions Spring MVC may raise a number of exceptions while processing @@ -3981,7 +3985,7 @@ public class SimpleController { ResponseEntityExceptionHandler for more details.
-
+
Annotating Business Exceptions With <interfacename>@ResponseStatus</interfacename> A business exception can be annotated with @@ -3994,7 +3998,7 @@ public class SimpleController {
-
+
Customizing the Default Servlet Container Error Page When the status of the response is set to an error status code @@ -4024,16 +4028,16 @@ public class SimpleController { @Controller public class ErrorController { - @RequestMapping(value="/error", produces="application/json") - @ResponseBody - public Map<String, Object> handle(HttpServletRequest request) { + @RequestMapping(value="/error", produces="application/json") + @ResponseBody + public Map<String, Object> handle(HttpServletRequest request) { - Map<String, Object> map = new HashMap<String, Object>(); - map.put("status", request.getAttribute("javax.servlet.error.status_code")); - map.put("reason", request.getAttribute("javax.servlet.error.message")); + Map<String, Object> map = new HashMap<String, Object>(); + map.put("status", request.getAttribute("javax.servlet.error.status_code")); + map.put("reason", request.getAttribute("javax.servlet.error.message")); - return map; - } + return map; + } } @@ -4049,7 +4053,7 @@ public class ErrorController {
-
+
Convention over configuration support For a lot of projects, sticking to established conventions and @@ -4067,7 +4071,7 @@ public class ErrorController { Convention-over-configuration support addresses the three core areas of MVC: models, views, and controllers. -
+
The Controller <classname>ControllerClassNameHandlerMapping</classname> @@ -4092,7 +4096,7 @@ public class ErrorController { configuration file: <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> - + <bean id="viewShoppingCart" class="x.y.z.ViewShoppingCartController"> <!-- inject dependencies as required... --> </bean> @@ -4165,7 +4169,7 @@ public class ErrorController { HandlerMapping implementations.
-
+
The Model <classname>ModelMap</classname> (<classname>ModelAndView</classname>) @@ -4181,10 +4185,10 @@ public class ErrorController { public class DisplayShoppingCartController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) { - - List cartItems = // get a List of CartItem objects - User user = // get the User doing the shopping - + + List cartItems = // get a List of CartItem objects + User user = // get the User doing the shopping + ModelAndView mav = new ModelAndView("displayShoppingCart"); <-- the logical view name mav.addObject(cartItems); <-- look ma, no name, just the object @@ -4293,7 +4297,7 @@ public class ErrorController {
-
+
The View - <interfacename>RequestToViewNameTranslator</interfacename> @@ -4307,21 +4311,21 @@ public class ErrorController { request URLs to logical view names, as with this example: public class RegistrationController implements Controller { - + public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) { // process the request... ModelAndView mav = new ModelAndView(); - // add data as necessary to the model... + // add data as necessary to the model... return mav; - // notice that no View or logical view name has been set + // notice that no View or logical view name has been set } } <?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 + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- this bean with the well known name generates view names for us --> @@ -4331,7 +4335,7 @@ public class ErrorController { <bean class="x.y.RegistrationController"> <!-- inject dependencies as necessary --> </bean> - + <!-- maps request URLs to Controller names --> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> @@ -4378,10 +4382,10 @@ public class ErrorController {
-
+
ETag support - An ETag + An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine change in content at a given URL. It can be considered to be the more sophisticated successor to the @@ -4420,12 +4424,12 @@ public class ErrorController { </filter-mapping>
-
+
Code-based Servlet container initialization In a Servlet 3.0+ environment, you have the option of configuring the Servlet container programmatically as an alternative or in combination with - a web.xml file. + a web.xml file. Below is an example of registering a DispatcherServlet: import org.springframework.web.WebApplicationInitializer; @@ -4436,12 +4440,12 @@ public class MyWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) { XmlWebApplicationContext appContext = new XmlWebApplicationContext(); appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml"); - + ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext)); registration.setLoadOnStartup(1); registration.addMapping("/"); } - + } WebApplicationInitializer is an interface @@ -4469,7 +4473,7 @@ public class MyWebApplicationInitializer implements WebApplicationInitializer { protected String[] getServletMappings() { return new String[] { "/" }; } - + } The above example is for an application that uses Java-based Spring @@ -4494,7 +4498,7 @@ public class MyWebApplicationInitializer implements WebApplicationInitializer { protected String[] getServletMappings() { return new String[] { "/" }; } - + } AbstractDispatcherServletInitializer also provides @@ -4522,92 +4526,92 @@ public class MyWebApplicationInitializer implements WebApplicationInitializer {
-
+
Configuring Spring MVC - and - explained about - Spring MVC's special beans and the default implementations - used by the DispatcherServlet. - In this section you'll learn about two additional ways of - configuring Spring MVC. Namely the MVC Java config and - the MVC XML namespace. - - - The MVC Java config and the MVC namespace provide - similar default configuration that overrides + and + explained about + Spring MVC's special beans and the default implementations + used by the DispatcherServlet. + In this section you'll learn about two additional ways of + configuring Spring MVC. Namely the MVC Java config and + the MVC XML namespace. + + + The MVC Java config and the MVC namespace provide + similar default configuration that overrides the DispatcherServlet defaults. - The goal is to spare most applications from having to + The goal is to spare most applications from having to having to create the same configuration and also to - provide higher-level constructs for configuring + provide higher-level constructs for configuring Spring MVC that serve as a simple starting point and - require little or no prior knowledge of the underlying + require little or no prior knowledge of the underlying configuration. - - You can choose either the MVC Java config or the + + You can choose either the MVC Java config or the MVC namespace depending on your preference. Also as you will see further below, with the MVC Java config it is - easier to see the underlying configuration as well as - to make fine-grained customizations directly to the - created Spring MVC beans. + easier to see the underlying configuration as well as + to make fine-grained customizations directly to the + created Spring MVC beans. But let's start from the beginning. - + -
- Enabling the MVC Java Config or the MVC XML Namespace - - To enable MVC Java config add the annotation - @EnableWebMvc to one of your - @Configuration classes: +
+ Enabling the MVC Java Config or the MVC XML Namespace - @Configuration + To enable MVC Java config add the annotation + @EnableWebMvc to one of your + @Configuration classes: + + @Configuration @EnableWebMvc public class WebConfig { } - To achieve the same in XML use the mvc:annotation-driven element: + To achieve the same in XML use the mvc:annotation-driven element: - <?xml version="1.0" encoding="UTF-8"?> + <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" - http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd - http://www.springframework.org/schema/mvc + http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <mvc:annotation-driven /> </beans> - + The above registers a - RequestMappingHandlerMapping, a + RequestMappingHandlerMapping, a RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver (among others) in support of processing requests with annotated controller methods using annotations such as @RequestMapping , @ExceptionHandler, and others. - It also enables the following: - + It also enables the following: + Spring 3 style type conversion through a ConversionService instance + linkend="core-convert">ConversionService instance in addition to the JavaBeans PropertyEditors used for Data Binding. Support for formatting Number - fields using the @NumberFormat + fields using the @NumberFormat annotation through the ConversionService. Support for formatting Date, - Calendar, Long, and Joda Time fields using the + Calendar, Long, and Joda Time fields using the @DateTimeFormat annotation. @@ -4615,15 +4619,15 @@ public class WebConfig { Support for validating @Controller - inputs with @Valid, + inputs with @Valid, if a JSR-303 Provider is present on the classpath. - HttpMessageConverter support for + HttpMessageConverter support for @RequestBody method parameters and @ResponseBody - method return values from + method return values from @RequestMapping or @ExceptionHandler methods. @@ -4688,20 +4692,20 @@ public class WebConfig { -
- -
- Customizing the Provided Configuration - - To customize the default configuration in Java you simply - implement the WebMvcConfigurer - interface or more likely extend the class - WebMvcConfigurerAdapter and override - the methods you need. Below is an example of some of the available - methods to override. See WebMvcConifgurer for - a list of all methods and the Javadoc for further details: - - @Configuration +
+ +
+ Customizing the Provided Configuration + + To customize the default configuration in Java you simply + implement the WebMvcConfigurer + interface or more likely extend the class + WebMvcConfigurerAdapter and override + the methods you need. Below is an example of some of the available + methods to override. See WebMvcConifgurer for + a list of all methods and the Javadoc for further details: + + @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @@ -4712,20 +4716,20 @@ public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { - // Configure the list of HttpMessageConverters to use + // Configure the list of HttpMessageConverters to use } - + } - - To customize the default configuration of + + To customize the default configuration of <mvc:annotation-driven /> check what - attributes and sub-elements it supports. You can view the - Spring MVC XML schema - or use the code completion feature of your IDE to discover - what attributes and sub-elements are available. - The sample below shows a subset of what is available: - - <mvc:annotation-driven conversion-service="conversionService"> + attributes and sub-elements it supports. You can view the + Spring MVC XML schema + or use the code completion feature of your IDE to discover + what attributes and sub-elements are available. + The sample below shows a subset of what is available: + + <mvc:annotation-driven conversion-service="conversionService"> <mvc:message-converters> <bean class="org.example.MyHttpMessageConverter"/> <bean class="org.example.MyOtherHttpMessageConverter"/> @@ -4740,10 +4744,10 @@ public class WebConfig extends WebMvcConfigurerAdapter { </list> </property> </bean> - -
-
+
+ +
Configuring Interceptors You can configure HandlerInterceptors @@ -4755,7 +4759,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LocaleInterceptor()); @@ -4783,7 +4787,7 @@ public class WebConfig extends WebMvcConfigurerAdapter {
-
+
Configuring Content Negotiation You can configure how Spring MVC determines requested media types for content negotiation purposes. @@ -4811,7 +4815,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { In XML you'll need to use the content-negotiation-manager property of annotation-driven: - <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /> + <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <property name="favorPathExtension" value="false" /> @@ -4824,9 +4828,9 @@ public class WebConfig extends WebMvcConfigurerAdapter { </property> </bean> -
+
-
+
Configuring View Controllers This is a shortcut for defining a @@ -4841,7 +4845,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("home"); @@ -4849,12 +4853,12 @@ public class WebConfig extends WebMvcConfigurerAdapter { } - And the same in XML use the <mvc:view-controller> element: + And the same in XML use the <mvc:view-controller> element: <mvc:view-controller path="/" view-name="home"/>
-
+
Configuring Serving of Resources This option allows static resource requests following a particular @@ -4874,10 +4878,10 @@ public class WebConfig extends WebMvcConfigurerAdapter { /resources/** from a public-resources directory within the web application root you would use: - @Configuration + @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/"); @@ -4885,7 +4889,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { } - And the same in XML: + And the same in XML: <mvc:resources mapping="/resources/**" location="/public-resources/"/> @@ -4893,10 +4897,10 @@ public class WebConfig extends WebMvcConfigurerAdapter { maximum use of the browser cache and a reduction in HTTP requests made by the browser: - @Configuration + @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/").setCachePeriod(31556926); @@ -4904,7 +4908,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { } - And in XML: + And in XML: <mvc:resources mapping="/resources/**" location="/public-resources/" cache-period="31556926"/> @@ -4919,10 +4923,10 @@ public class WebConfig extends WebMvcConfigurerAdapter { /META-INF/public-web-resources/ in any jar on the classpath use: - @EnableWebMvc + @EnableWebMvc @Configuration public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") @@ -4931,7 +4935,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { } - And in XML: + And in XML: <mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/public-web-resources/"/> @@ -4961,16 +4965,16 @@ public class WebConfig extends WebMvcConfigurerAdapter { as a bean using the util:properties tag: <util:properties id="applicationProps" location="/WEB-INF/spring/application.properties"/> - + With the application version now accessible via SpEL, we can incorporate this into the use of the resources tag: <mvc:resources mapping="/resources-#{applicationProps['application.version']}/**" location="/public-resources/"/> - + In Java, you can use the @PropertySouce - annotation and then inject the Environment + annotation and then inject the Environment abstraction for access to all defined properties: - + @Configuration @EnableWebMvc @PropertySource("/WEB-INF/spring/application.properties") @@ -4998,7 +5002,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { <script src="${resourceUrl}/dojo/dojo.js" type="text/javascript"> </script>
-
+
mvc:default-servlet-handler This tag allows for mapping the DispatcherServlet to @@ -5019,19 +5023,19 @@ public class WebConfig extends WebMvcConfigurerAdapter { To enable the feature using the default setup use: - @Configuration + @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { - configurer.enable(); + configurer.enable(); } } - Or in XML: - + Or in XML: + <mvc:default-servlet-handler/> The caveat to overriding the "/" Servlet mapping is that the @@ -5046,13 +5050,13 @@ public class WebConfig extends WebMvcConfigurerAdapter { the default Servlet name is unknown, then the default Servlet's name must be explicitly provided as in the following example: - @Configuration + @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { - + @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { - configurer.enable("myCustomDefaultServlet"); + configurer.enable("myCustomDefaultServlet"); } } @@ -5062,19 +5066,19 @@ public class WebConfig extends WebMvcConfigurerAdapter { <mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>
-
+
More Spring Web MVC Resources - + See the following links and pointers for more resources about Spring Web MVC: - + There are many excellent articles and tutorials that show how to - build web applications with Spring MVC. Read them at the Spring - Documentation page. + build web applications with Spring MVC. Read them at the Spring + Documentation page. - + Expert Spring Web MVC and Web Flow by Seth Ladd and others (published by Apress) is an excellent hard copy source of @@ -5082,36 +5086,36 @@ public class WebConfig extends WebMvcConfigurerAdapter {
- -
+ +
Advanced Customizations with MVC Java Config - + As you can see from the above examples, MVC Java config and - the MVC namespace provide higher level constructs that do not - require deep knowledge of the underlying beans created for you. + the MVC namespace provide higher level constructs that do not + require deep knowledge of the underlying beans created for you. Instead it helps you to focus on your application needs. However, at some point you may need more fine-grained control or you may simply wish to understand the underlying configuration. - - The first step towards more fine-grained control is to see the - underlying beans created for you. In MVC Java config you can + + The first step towards more fine-grained control is to see the + underlying beans created for you. In MVC Java config you can see the Javadoc and the @Bean methods in WebMvcConfigurationSupport. - The configuration in this class is automatically imported - through the @EnableWebMvc annotation. + The configuration in this class is automatically imported + through the @EnableWebMvc annotation. In fact if you open @EnableWebMvc you can see the @Import statement. - - The next step towards more fine-grained control is to + + The next step towards more fine-grained control is to customize a property on one of the beans created in WebMvcConfigurationSupport or perhaps - to provide your own instance. This requires two things -- - remove the @EnableWebMvc - annotation in order to prevent the import and then + to provide your own instance. This requires two things -- + remove the @EnableWebMvc + annotation in order to prevent the import and then extend directly from WebMvcConfigurationSupport. Here is an example: - + @Configuration public class WebConfig extends WebMvcConfigurationSupport { @@ -5124,47 +5128,47 @@ public class WebConfig extends WebMvcConfigurationSupport { @Bean public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { - // Create or let "super" create the adapter - // Then customize one of its properties + // Create or let "super" create the adapter + // Then customize one of its properties } - + } - + Note that modifying beans in this way does not prevent - you from using any of the higher-level constructs shown earlier in + you from using any of the higher-level constructs shown earlier in this section. - +
- -
+ +
Advanced Customizations with the MVC Namespace - + Fine-grained control over the configuration created for you is a bit harder with the MVC namespace. - - If you do need to do that, rather than replicating the - configuration it provides, consider configuring a + + If you do need to do that, rather than replicating the + configuration it provides, consider configuring a BeanPostProcessor that detects - the bean you want to customize by type and then modifying its + the bean you want to customize by type and then modifying its properties as necessary. For example: - + @Component public class MyPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException { if (bean instanceof RequestMappingHandlerAdapter) { - // Modify properties of the adapter + // Modify properties of the adapter } } } - - Note that MyPostProcessor needs to be - included in an <component scan /> + + Note that MyPostProcessor needs to be + included in an <component scan /> in order for it to be detected or if you prefer you can declare it explicitly with an XML bean declaration.
- + diff --git a/src/reference/docbook/new-in-3.0.xml b/src/reference/docbook/new-in-3.0.xml index 018873f8a9..612161ad56 100644 --- a/src/reference/docbook/new-in-3.0.xml +++ b/src/reference/docbook/new-in-3.0.xml @@ -1,8 +1,12 @@ - + 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"> New Features and Enhancements in Spring 3.0 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. - + Java SE and Java EE Support 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. -
+
Java 5 The entire framework code has been revised to take advantage of Java @@ -44,7 +48,7 @@ @Asynchronous annotation).
-
+
Improved documentation 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 raising an - issue. + team by raising an + issue.
-
+
New articles and tutorials - There are many excellent articles and tutorials that show how to get started with Spring 3 features. - Read them at the Spring Documentation page. - - - 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 - repository available at: - + There are many excellent articles and tutorials that show how to get started with Spring 3 features. + Read them at the Spring Documentation page. + + + 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 + repository available at: + - https://anonsvn.springframework.org/svn/spring-samples/ - - - 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. - - For more information on Subversion (or in short SVN), see the project homepage at: - http://subversion.apache.org/ - + https://anonsvn.springframework.org/svn/spring-samples/ + + + 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. + + For more information on Subversion (or in short SVN), see the project homepage at: + http://subversion.apache.org/ +
-
+
New module organization and build system The framework modules have been revised and are now managed @@ -154,7 +158,7 @@ - + Note: The spring.jar artifact that contained almost the entire framework @@ -183,7 +187,7 @@
-
+
Overview of new features This is a list of new features for Spring 3.0. We will cover these @@ -229,7 +233,7 @@ -
+
Core APIs updated for Java 5 BeanFactory interface returns typed bean instances as far as @@ -269,7 +273,7 @@ Typed ApplicationListener<E>
-
+
Spring Expression Language 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 SpringSource - Tool Suite. + Eclipse based SpringSource + Tool Suite. The following is an example of how the Expression Language can be used to configure some properties of a database setup This functionality is also available if you prefer to configure - your components using annotations: @Repository + your components using annotations: @Repository public class RewardsTestDatabase { @Value("#{systemProperties.databaseName}") @@ -311,14 +315,14 @@ public class RewardsTestDatabase {
-
+
The Inversion of Control (IoC) container -
+
Java based bean metadata - Some core features from the JavaConfig + Some core features from the JavaConfig project have been added to the Spring Framework now. This means that the following annotations are now directly supported: @@ -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 { AnnotationConfigApplicationContext.
-
+
Defining bean metadata within components @Bean annotated methods are also supported @@ -415,7 +419,7 @@ public class AppConfig {
-
+
General purpose type conversion system and field formatting system @@ -430,7 +434,7 @@ public class AppConfig { environments such as Spring MVC.
-
+
The Data Tier Object to XML mapping functionality (OXM) from the Spring Web @@ -441,14 +445,14 @@ public class AppConfig { Mappers chapter.
-
+
The Web Tier 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. -
+
Comprehensive REST support Server-side support for building RESTful applications has been @@ -471,7 +475,7 @@ public class AppConfig { information.
-
+
@MVC additions A mvc namespace has been introduced that greatly simplifies Spring MVC configuration. @@ -486,14 +490,14 @@ public class AppConfig {
-
+
Declarative model validation Several validation enhancements, including JSR 303 support that uses Hibernate Validator as the default provider.
-
+
Early support for Java EE 6 We provide support for asynchronous method invocations through the @@ -504,7 +508,7 @@ public class AppConfig {
-
+
Support for embedded databases Convenient support for - + 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"> New Features and Enhancements in Spring 3.1 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. -
+
Overview of new features 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. -
+
Cache Abstraction @@ -25,27 +29,27 @@ - - Cache Abstraction (SpringSource team blog) + + Cache Abstraction (SpringSource team blog)
-
+
Bean Definition Profiles - - XML profiles (SpringSource Team Blog) + + XML profiles (SpringSource Team Blog) - - Introducing @Profile (SpringSource Team Blog) + + Introducing @Profile (SpringSource Team Blog) @@ -60,14 +64,14 @@
-
+
Environment Abstraction - - Environment Abstraction (SpringSource Team Blog) + + Environment Abstraction (SpringSource Team Blog) @@ -76,14 +80,14 @@
-
+
PropertySource Abstraction - - Unified Property Management (SpringSource Team Blog) + + Unified Property Management (SpringSource Team Blog) @@ -101,7 +105,7 @@
-
+
Code equivalents for Spring's XML namespaces Code-based equivalents to popular Spring XML namespace elements @@ -169,7 +173,7 @@
-
+
Support for Hibernate 4.x @@ -180,7 +184,7 @@
-
+
TestContext framework support for @Configuration classes and bean definition profiles @@ -195,9 +199,9 @@ - Spring - 3.1 M2: Testing with @Configuration Classes and Profiles + Spring + 3.1 M2: Testing with @Configuration Classes and Profiles (SpringSource Team Blog) @@ -238,7 +242,7 @@
-
+
c: namespace for more concise constructor injection @@ -248,7 +252,7 @@
-
+
Support for injection against non-standard JavaBeans setters @@ -260,7 +264,7 @@ setter methods return a reference to 'this'.
-
+
Support for Servlet 3 code-based configuration of Servlet Container @@ -276,15 +280,15 @@ - Diff from Spring's - Greenhouse reference application demonstrating migration + Diff from Spring's + Greenhouse reference application demonstrating migration from web.xml to WebApplicationInitializer
-
+
Support for Servlet 3 MultipartResolver @@ -296,7 +300,7 @@
-
+
JPA EntityManagerFactory bootstrapping without persistence.xml @@ -320,7 +324,7 @@ initializer.
-
+
New HandlerMethod-based Support Classes For Annotated Controller Processing @@ -380,7 +384,7 @@ A second notable difference is the introduction of a HandlerMethod abstraction to represent an - @RequestMapping method. This abstraction is used + @RequestMapping method. This abstraction is used throughout by the new support classes as the handler instance. For example a HandlerInterceptor can cast the handler from Object @@ -388,7 +392,7 @@ controller method, its annotations, etc. The new classes are enabled by default by the MVC namespace and by - Java-based configuration via @EnableWebMvc. The + Java-based configuration via @EnableWebMvc. The existing classes will continue to be available but use of the new classes is recommended going forward. @@ -397,9 +401,9 @@
-
+
"consumes" and "produces" conditions in - <interface>@RequestMapping</interface> + @RequestMapping Improved support for specifying media types consumed by a method through the 'Content-Type' header as well as for @@ -408,7 +412,7 @@ linkend="mvc-ann-requestmapping-produces" />
-
+
Flash Attributes and <interfacename>RedirectAttributes</interfacename> @@ -426,7 +430,7 @@ for more details.
-
+
URI Template Variable Enhancements URI template variables from the current request are used in more @@ -461,20 +465,20 @@
-
+
<interfacename>@Valid</interfacename> On - <interface>@RequestBody</interface> Controller Method Arguments + @RequestBody Controller Method Arguments - An @RequestBody method argument can be - annotated with @Valid to invoke automatic + An @RequestBody method argument can be + annotated with @Valid to invoke automatic validation similar to the support for - @ModelAttribute method arguments. A resulting + @ModelAttribute method arguments. A resulting MethodArgumentNotValidException is handled in the DefaultHandlerExceptionResolver and results in a 400 response code.
-
+
<interfacename>@RequestPart</interfacename> Annotation On Controller Method Arguments @@ -484,7 +488,7 @@ linkend="mvc-multipart" />.
-
+
<classname>UriComponentsBuilder</classname> and <classname>UriComponents</classname> A new UriComponents class has been added, diff --git a/src/reference/docbook/new-in-3.2.xml b/src/reference/docbook/new-in-3.2.xml index 9b98f845c8..c2968b065e 100644 --- a/src/reference/docbook/new-in-3.2.xml +++ b/src/reference/docbook/new-in-3.2.xml @@ -1,19 +1,23 @@ - + 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"> New Features and Enhancements in Spring 3.2 -
+
Overview of new features -
+
Support for Servlet 3 based asynchronous request processing The Spring MVC programming model now provides explicit Servlet 3 async support. @RequestMapping methods can return one of: - + java.util.concurrent.Callable to @@ -31,14 +35,14 @@ customize the timeout value or the task executor to use. - - See - Introducing Servlet 3 Async Support (SpringSource team blog). - + + See + Introducing Servlet 3 Async Support (SpringSource team blog). +
-
+
Spring MVC Test framework First-class support for testing Spring MVC applications with a @@ -47,13 +51,13 @@ REST tests rely on the RestTemplate. See the following presentation for more information before documentation is added: - - "Testing Web Applications with Spring 3.2". + + "Testing Web Applications with Spring 3.2".
-
+
Content negotiation improvements A ContentNeogtiationStrategy is now @@ -75,14 +79,14 @@ The introduction of ContentNegotiationManger also enables smart suffix pattern matching for incoming requests. - See - commit message + See + commit message
-
+
<interfacename>@ControllerAdvice</interfacename> annotation - + Classes annotated with @ControllerAdvice can contain @ExceptionHandler, @InitBinder, and @@ -92,10 +96,10 @@ @ControllerAdvice is a component annotation allowing implementation classes to be auto-detected through classpath scanning. - +
-
+
Matrix variables A new @MatrixVariable annotation @@ -103,7 +107,7 @@ For more details see .
-
+
Abstract base class for code-based Servlet 3+ container initialization An abstract base class implementation of the @@ -116,7 +120,7 @@ For more details see .
-
+
<classname>ResponseEntityExceptionHandler</classname> class A convenient base class with an @@ -132,7 +136,7 @@
-
+
Support for generic types in the <classname>RestTemplate</classname> and in <interfacename>@RequestBody</interfacename> arguments @@ -152,10 +156,10 @@ generic type is a JAXB type annotated with @XmlRootElement or @XmlType. - +
-
+
Jackson JSON 2 and related improvements The Jackson Json 2 library is now supported. Due to packaging changes in @@ -170,7 +174,7 @@
-
+
<interfacename>@RequestBody</interfacename> improvements An @RequestBody or an @@ -183,7 +187,7 @@
-
+
HTTP PATCH method The HTTP request method PATCH may now be used in @@ -195,7 +199,7 @@
-
+
Excluded patterns in mapped interceptors Mapped interceptors now support URL patterns to be excluded. diff --git a/src/reference/docbook/orm.xml b/src/reference/docbook/orm.xml index 9e5fad0ab3..24c071a473 100644 --- a/src/reference/docbook/orm.xml +++ b/src/reference/docbook/orm.xml @@ -1,11 +1,15 @@ - + 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"> Object Relational Mapping (ORM) Data Access -
+
Introduction to ORM with Spring The Spring Framework supports integration @@ -42,7 +46,7 @@ it easy to swap the implementations and configuration locations of Hibernate SessionFactory instances, JDBC DataSource instances, transaction - managers, and mapped object implementations (if needed). This in turn makes it much easier to test each piece of persistence-related code in isolation. @@ -75,7 +79,7 @@ TR: OK. Refers only to mapped object implementations-->This in turn makes it Session to ensure efficiency and proper transaction handling. Spring makes it easy to create and bind a Session to the current thread - transparently, by exposing a current Session through the Hibernate SessionFactory. Thus Spring @@ -105,15 +109,15 @@ TR: REVISED, PLS REVIEW. Good point, removed coverage of template wrapper.-->by - TODO: provide links to current samples
-
+
General ORM integration considerations 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. -
+
Resource and transaction management 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 in the case of JDBC and applying AOP interceptors for the ORM technologies. @@ -170,7 +174,7 @@ TR: OK AS IS. The template for JDBC is still recommended--> in the case of chapter.
-
+
Exception translation When you use Hibernate, JPA, or JDO in a DAO, you must decide how @@ -200,7 +204,7 @@ public class ProductDaoImpl implements ProductDao { <beans> - <!-- Exception translation bean post processor --> + <!-- Exception translation bean post processor --> <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> <bean id="myProductDao" class="product.ProductDaoImpl"/> @@ -223,11 +227,11 @@ public class ProductDaoImpl implements ProductDao {
-
+
Hibernate - We will start with a coverage of Hibernate 3 in a Spring + We will start with a coverage of Hibernate 3 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 { As of Spring 3.0, Spring requires Hibernate 3.2 or later. -
+
<interfacename>SessionFactory</interfacename> setup in a Spring container @@ -298,7 +302,7 @@ public class ProductDaoImpl implements ProductDao { However, that is typically not common outside of an EJB context.
-
+
Implementing DAOs based on plain Hibernate 3 API Hibernate 3 has a feature called contextual sessions, wherein @@ -382,14 +386,14 @@ public class ProductDaoImpl implements ProductDao { transactions.
-
+
Declarative transaction demarcation 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.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"> - <!-- SessionFactory, DataSource, etc. omitted --> + <!-- SessionFactory, DataSource, etc. omitted --> - <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"> - <!-- SessionFactory, DataSource, etc. omitted --> + <!-- SessionFactory, DataSource, etc. omitted --> <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>
-
+
Programmatic transaction demarcation 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.
-
+
Transaction management strategies Both TransactionTemplate and @@ -722,12 +726,12 @@ TR: OK. Reads OK to me, it applies to both. --> HibernateTransactionManager class.
-
- 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--> You can switch between a container-managed JNDI - SessionFactory 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 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. 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.
-
+
Spurious application server warnings with Hibernate 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 PlatformTransactionManager object (presumably from JNDI through - JndiObjectFactoryBean/<jee:jndi-lookup>) + JndiObjectFactoryBean or <jee:jndi-lookup>) and feeding it, for example, to Spring's JtaTransactionManager, 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- More likely you do not already have the JTA PlatformTransactionManager instance, because Spring's JtaTransactionManager can - find it itself. Thus you need to configure Hibernate to look up JTA PlatformTransactionManager directly. @@ -863,7 +867,7 @@ TR: OK AS IS. This is very container dependent, and either case is possible.-->T Among other activities, this synchronization can trigger a callback by Spring to Hibernate, through Hibernate's - afterTransactionCompletion callback (used to clear the Hibernate cache), followed by an explicit close() call on the Hibernate Session, which @@ -918,7 +922,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
-
+
JDO 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 org.springframework.orm.jdo package. -
+
<interfacename>PersistenceManagerFactory</interfacename> setup @@ -955,8 +959,8 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio usually supports a Spring-defined JDBC DataSource, passed into the connectionFactory property. For example, for the - open source JDO implementation DataNucleus (formerly JPOX) (http://www.datanucleus.org/), + open source JDO implementation DataNucleus (formerly JPOX) (http://www.datanucleus.org/), this is the XML configuration of the PersistenceManagerFactory implementation: @@ -981,8 +985,8 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio PersistenceManagerFactory in the JNDI environment of a Java EE application server, usually through the JCA connector provided by the particular JDO implementation. Spring's - standard JndiObjectFactoryBean / - <jee:jndi-lookup> can be used to + standard JndiObjectFactoryBean or + <jee:jndi-lookup> can be used to retrieve and expose such a PersistenceManagerFactory. 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.
-
+
Implementing DAOs based on the plain JDO API 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); } } @@ -1130,7 +1134,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio DataAccessException (if desired).
-
+
Transaction management @@ -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.
-
+
<interfacename>JdoDialect</interfacename> As an advanced feature, both JdoTemplate @@ -1250,25 +1254,25 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio
-
+
JPA The Spring JPA, available under the org.springframework.orm.jpa package, offers - comprehensive support for the Java - Persistence API in a similar manner to the integration with + comprehensive support for the Java + Persistence API in a similar manner to the integration with Hibernate or JDO, while being aware of the underlying implementation in order to provide additional features. -
+
Three options for JPA setup in a Spring environment The Spring JPA support offers three ways of setting up the JPA EntityManagerFactory that will be used by the application to obtain an entity manager. -
+
<classname>LocalEntityManagerFactoryBean</classname> @@ -1279,7 +1283,7 @@ TR: OK AS IS. Two different callback methhods - one is Spring's (*afterCompletio The LocalEntityManagerFactoryBean creates an EntityManagerFactory suitable for simple deployment environments where the application uses only JPA for - data access. The factory bean uses the JPA PersistenceProvider 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.
-
+
Obtaining an <classname>EntityManagerFactory</classname> from JNDI @@ -1352,7 +1356,7 @@ TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA @PersistenceContext annotations.
-
+
<classname>LocalContainerEntityManagerFactoryBean</classname> @@ -1377,14 +1381,14 @@ TR: REVISED, PLS REVIEW.-->The factory bean uses the JPA LocalContainerEntityManagerFactoryBean: <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> 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 DataSource, supports both local and global transactions, and so on. However, it also imposes - requirements on the runtime environment, such as the availability of a weaving-capable class loader if the persistence provider demands byte-code transformation. @@ -1454,8 +1458,8 @@ TR: OK AS IS. The requirement is to provide the classloader for the runtime envi ClassTransformer instances to be plugged in a specific manner, depending whether the environment is a web container or application server. - Hooking ClassTransformers through a Java 5 agent + Hooking ClassTransformers through a Java 5 agent typically is not efficient. The agents work against the entire virtual machine and inspect every 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 per class loader and not per VM. - Refer to in the AOP chapter for more insight regarding the - LoadTimeWeaver implementations and their setup, either generic or customized to + Refer to in the AOP chapter for more insight regarding the + LoadTimeWeaver implementations and their setup, either generic or customized to various platforms (such as Tomcat, WebLogic, OC4J, GlassFish, Resin and JBoss). - - - As described in the aforementioned section, you can configure a context-wide LoadTimeWeaver - using the @EnableLoadTimeWeaving annotation of context:load-time-weaver XML element. - Such a global weaver is picked up by all JPA LocalContainerEntityManagerFactoryBeans - automatically. This is the preferred way of setting up a load-time weaver, delivering autodetection of the platform + + + As described in the aforementioned section, you can configure a context-wide LoadTimeWeaver + using the @EnableLoadTimeWeaving annotation of context:load-time-weaver XML element. + Such a global weaver is picked up by all JPA LocalContainerEntityManagerFactoryBeans + 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: - - <context:load-time-weaver/> + + <context:load-time-weaver/> <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> ... </bean> - - However, if needed, one can manually specify a dedicated weaver through the loadTimeWeaver property: + + However, if needed, one can manually specify a dedicated weaver through the loadTimeWeaver property: <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> 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. - + -->
-
+
Dealing with multiple persistence units For applications that rely on multiple persistence units @@ -1560,7 +1564,7 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --> -
+
Setting up the <classname>SqlMapClient</classname> Using iBATIS SQL Maps involves creating SqlMap configuration files @@ -1854,12 +1858,12 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --> 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>
-
+
Using <classname>SqlMapClientTemplate</classname> and <classname>SqlMapClientDaoSupport</classname> @@ -1999,7 +2003,7 @@ Makes you wonder if anyone actually reads thes docs :)--> with iBATIS 2.x we hierarchy.
-
+
Implementing DAOs based on plain iBATIS API 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: public class SqlMapAccountDao implements AccountDao { - + private SqlMapClient sqlMapClient; - + public void setSqlMapClient(SqlMapClient sqlMapClient) { this.sqlMapClient = sqlMapClient; } diff --git a/src/reference/docbook/overview.xml b/src/reference/docbook/overview.xml index ee94930be0..d01981d5e7 100644 --- a/src/reference/docbook/overview.xml +++ b/src/reference/docbook/overview.xml @@ -1,8 +1,12 @@ - + 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"> Introduction to Spring Framework Spring Framework is a Java platform that provides comprehensive @@ -39,10 +43,10 @@ -
+
Dependency Injection and Inversion of Control - + Background 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 Dependency Injection. - For insight into IoC and DI, refer to Fowler's article at http://martinfowler.com/articles/injection.html. + For insight into IoC and DI, refer to Fowler's article at http://martinfowler.com/articles/injection.html. 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, maintainable applications.
-
+
Modules 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
-
+
Core Container The Core @@ -150,7 +154,7 @@ TR: This section doesn't read well and I think we should try to rewrite it.-->Nu aggregations.
-
+
Data Access/Integration The Data Access/Integration 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).
-
+
Web The Web 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">MVC) 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. The Web-Struts module contains the support @@ -215,7 +219,7 @@ It sounds important.--> functionality of Web-Servlet module.
-
+
AOP and Instrumentation Spring's certain application servers.
-
+
Test The Test module supports the testing of @@ -248,7 +252,7 @@ TR: OK. Added to diagram.-->
-
+
Usage scenarios The building blocks described previously make Spring a logical @@ -353,7 +357,7 @@ TR: OK. Added to diagram.--> scalable, fail-safe web applications that might need declarative security. -
+
Dependency Management and Naming Conventions Dependency management and dependency injection are different @@ -386,8 +390,8 @@ TR: OK. Added to diagram.--> In general, Spring publishes its artifacts to four different places: - On the community download site http://www.springsource.org/downloads/community. + On the community download site http://www.springsource.org/downloads/community. 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.--> (org.springframework.*-<version>.jar), and the dependencies are also in this "long" form, with external libraries (not from SpringSource) having the prefix - com.springsource. See the FAQ + com.springsource. See the FAQ for more information. @@ -553,8 +557,8 @@ TR: OK. Added to diagram.--> Various - http://www.springsource.com/repository + http://www.springsource.com/repository @@ -570,7 +574,7 @@ TR: OK. Added to diagram.-->
Overview of the Spring Framework
-
+
Spring Dependencies and Depending on Spring Although Spring provides integration and support for a huge @@ -590,7 +594,7 @@ TR: OK. Added to diagram.--> our samples mostly use Maven.
-
+
Maven Dependency Management If you are using Maven for dependency management you don't even @@ -671,18 +675,18 @@ TR: OK. Added to diagram.--> 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 http://www.springsource.com/repository + interface at http://www.springsource.com/repository 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.
-
+
Ivy Dependency Management - If you prefer to use Ivy to manage dependencies + If you prefer to use Ivy to manage dependencies then there are similar names and configuration options. To configure Ivy to point to the SpringSource EBR add the @@ -690,7 +694,7 @@ TR: OK. Added to diagram.--> ivysettings.xml: <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.--> <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.--> include in your dependencies section. For example (in ivy.xml): - <dependency org="org.springframework" + <dependency org="org.springframework" name="org.springframework.core" rev="3.0.0.RELEASE" conf="compile->runtime"/>
-
+
Logging Logging is a very important dependency for Spring because a) it is @@ -763,15 +767,15 @@ TR: OK. Added to diagram.--> application works and logs happily to the console out of the box in most situations, and that's important. -
+
Not Using Commons Logging Unfortunately, the runtime discovery algorithm in commons-logging, 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 (SLF4J), which is also used by a lot + first choice would probably be the Simple Logging Facade for Java (SLF4J), which is also used by a lot of other tools that people use with Spring inside their applications. @@ -801,94 +805,94 @@ TR: OK. Added to diagram.--> alternative implementation of JCL using SLF4J as an example.
-
+
Using SLF4J + + SLF4J is a cleaner dependency and more efficient at runtime than + commons-logging 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. + + 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 commons-logging 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. + + 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 commons-logging): + the bridge, the SLF4J API, the binding to Log4J, and the Log4J + implementation itself. In Maven you would do that like this + + <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> + + That might seem like a lot of dependencies just to get some + logging. Well it is, but it is optional, and it + should behave better than the vanilla commons-logging 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. + + A more common choice amongst SLF4J users, which uses fewer steps + and generates fewer dependencies, is to bind directly to Logback. This removes the extra + binding step because Logback implements SLF4J directly, so you only need + to depend on two libraries not four (jcl-over-slf4j and + logback). 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.
- SLF4J is a cleaner dependency and more efficient at runtime than - commons-logging 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. - - 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 commons-logging 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. - - 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 commons-logging): - the bridge, the SLF4J API, the binding to Log4J, and the Log4J - implementation itself. In Maven you would do that like this - - <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> - - That might seem like a lot of dependencies just to get some - logging. Well it is, but it is optional, and it - should behave better than the vanilla commons-logging 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. - - A more common choice amongst SLF4J users, which uses fewer steps - and generates fewer dependencies, is to bind directly to Logback. This removes the extra - binding step because Logback implements SLF4J directly, so you only need - to depend on two libraries not four (jcl-over-slf4j and - logback). 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. - -
+
Using Log4J - Many people use Log4j as a logging + Many people use Log4j 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 -
+
Runtime Containers with Native JCL Many people run their Spring applications in a container that diff --git a/src/reference/docbook/oxm.xml b/src/reference/docbook/oxm.xml index 2cc0563c5f..04526df4fa 100644 --- a/src/reference/docbook/oxm.xml +++ b/src/reference/docbook/oxm.xml @@ -1,11 +1,15 @@ - + 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"> Marshalling XML using O/X Mappers -
+
Introduction 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. - Within the field of O/X mapping, a marshaller is responsible for serializing an + Within the field of O/X mapping, a marshaller is responsible for serializing an object (graph) to XML. In similar fashion, an unmarshaller 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. @@ -30,12 +34,12 @@ Consistent Interfaces - Spring's O/X mapping operates through two global interfaces: the - Marshaller and Unmarshaller 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 + Marshaller and Unmarshaller 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. @@ -48,18 +52,18 @@
-
+
Marshaller and Unmarshaller As stated in the introduction, a marshaller serializes an object to XML, and an unmarshaller deserializes XML stream to an object. In this section, we will describe the two Spring interfaces used for this purpose. -
+
Marshaller - Spring abstracts all marshalling operations behind the - org.springframework.oxm.Marshaller interface, the main methods of which + Spring abstracts all marshalling operations behind the + org.springframework.oxm.Marshaller interface, the main methods of which is listed below. The Marshaller interface has one main method, which marshals the given - object to a given javax.xml.transform.Result. Result is a tagging + object to a given javax.xml.transform.Result. Result is a tagging interface that basically represents an XML output abstraction: concrete implementations wrap various XML representations, as indicated in the table below. @@ -104,8 +108,8 @@ public interface Marshaller { - Although the marshal() method accepts a plain object as its first - parameter, most Marshaller implementations cannot handle arbitrary + Although the marshal() method accepts a plain object as its first + parameter, most Marshaller 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 {
-
+
Unmarshaller - Similar to the Marshaller, there is the + Similar to the Marshaller, there is the org.springframework.oxm.Unmarshaller interface. - This interface also has one method, which reads from the given + This interface also has one method, which reads from the given javax.xml.transform.Source (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 { + + Even though there are two separate marshalling interfaces (Marshaller + and Unmarshaller), 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 applicationContext.xml. +
- - Even though there are two separate marshalling interfaces (Marshaller - and Unmarshaller), 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 applicationContext.xml. - -
+
XmlMappingException 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 - + + @@ -208,7 +213,7 @@ public interface Unmarshaller {
-
+
Using Marshaller and Unmarshaller 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 { ]]>
-
- XML Schema-based Configuration - - 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: - - +
+ XML Schema-based Configuration + + 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: + + @@ -333,48 +338,48 @@ public class Application { ]]> ]]> - - Currently, the following tags are available: - - - jaxb2-marshaller - - - xmlbeans-marshaller - - - jibx-marshaller - - - - - 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: - - ]]> -
-
+ + Currently, the following tags are available: + + + jaxb2-marshaller + + + xmlbeans-marshaller + + + jibx-marshaller + + + + + 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: + + ]]> +
+
JAXB - The JAXB binding compiler translates a W3C XML Schema into one or more Java classes, a - jaxb.properties 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 + jaxb.properties file, and possibly some resource files. JAXB also offers a way to generate a schema from annotated Java classes. Spring supports the JAXB 2.0 API as XML marshalling strategies, following the Marshaller and Unmarshaller - interfaces described in . The corresponding integration + interfaces described in . The corresponding integration classes reside in the org.springframework.oxm.jaxb package. -
+
Jaxb2Marshaller The Jaxb2Marshaller class implements both the Spring Marshaller and Unmarshallerinterface. It requires a context path to operate, which you can set using the contextPath property. The context path is a list of colon (:) separated Java package names that contain schema - derived classes. It also offers a classesToBeBound 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 classesToBeBound 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: org.springframework.oxm.jaxb.Flight - org.springframework.oxm.jaxb.Flights + org.springframework.oxm.jaxb.Flights @@ -392,29 +397,29 @@ public class Application { ... ]]> -
- XML Schema-based Configuration - - The jaxb2-marshaller tag configures a org.springframework.oxm.jaxb.Jaxb2Marshaller. - Here is an example: - - ]]> - - Alternatively, the list of classes to bind can be provided to the marshaller via the class-to-be-bound child tag: - - +
+ XML Schema-based Configuration + + The jaxb2-marshaller tag configures a org.springframework.oxm.jaxb.Jaxb2Marshaller. + Here is an example: + + ]]> + + Alternatively, the list of classes to bind can be provided to the marshaller via the class-to-be-bound child tag: + + ... - ]]> - - Available attributes are: + ]]> + + Available attributes are: - - - + + + Attribute @@ -436,11 +441,11 @@ public class Application { - -
+ +
-
+
Castor 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. - For more information on Castor, refer to the - Castor web site. The Spring integration classes reside in the + For more information on Castor, refer to the + Castor web site. The Spring integration classes reside in the org.springframework.oxm.castor package. -
+
CastorMarshaller - As with JAXB, the CastorMarshaller implements both the - Marshaller and Unmarshaller interface. + As with JAXB, the CastorMarshaller implements both the + Marshaller and Unmarshaller interface. It can be wired up as follows: ]]>
-
+
Mapping 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 Castor XML Mapping. + to Castor XML Mapping. The mapping can be set using the mappingLocation resource property, indicated @@ -488,7 +493,7 @@ public class Application {
-
+
XMLBeans XMLBeans is an XML binding tool that has full XML Schema support, and offers full XML Infoset @@ -497,11 +502,11 @@ public class Application { XmlObject, and contain XML binding information in them. - For more information on XMLBeans, refer to the - XMLBeans web site . The Spring-WS integration classes reside + For more information on XMLBeans, refer to the + XMLBeans web site . The Spring-WS integration classes reside in the org.springframework.oxm.xmlbeans package. -
+
XmlBeansMarshaller The XmlBeansMarshaller @@ -523,20 +528,20 @@ public class Application { and not every java.lang.Object. -
- XML Schema-based Configuration - - The xmlbeans-marshaller tag configures a org.springframework.oxm.xmlbeans.XmlBeansMarshaller. - Here is an example: - - ]]> - - Available attributes are: +
+ XML Schema-based Configuration + + The xmlbeans-marshaller tag configures a org.springframework.oxm.xmlbeans.XmlBeansMarshaller. + Here is an example: + + ]]> + + Available attributes are: - - - + + + Attribute @@ -559,14 +564,14 @@ public class Application { - -
+
+
-
+
JiBX 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. - For more information on JiBX, refer to the - JiBX web site. The Spring integration classes reside in the + For more information on JiBX, refer to the + JiBX web site. The Spring integration classes reside in the org.springframework.oxm.jibx package. -
+
JibxMarshaller - The JibxMarshaller class implements both the + The JibxMarshaller class implements both the Marshaller and Unmarshaller interface. To operate, it requires the name of the class to marshal in, which you can set using the targetClass property. Optionally, you can set the binding name using the - bindingName property. In the next sample, we bind the + bindingName property. In the next sample, we bind the Flights class: JibxMarshallers with different targetClass property values. -
- XML Schema-based Configuration - - The jibx-marshaller tag configures a org.springframework.oxm.jibx.JibxMarshaller. - Here is an example: - - ]]> - - Available attributes are: +
+ XML Schema-based Configuration + + The jibx-marshaller tag configures a org.springframework.oxm.jibx.JibxMarshaller. + Here is an example: + + ]]> + + Available attributes are: - - - + + + Attribute @@ -643,26 +648,26 @@ public class Application { - -
+
+
-
+
XStream XStream is a simple library to serialize objects to XML and back again. It does not require any mapping, and generates clean XML. - For more information on XStream, refer to the - XStream web site. The Spring integration classes reside in the + For more information on XStream, refer to the + XStream web site. The Spring integration classes reside in the org.springframework.oxm.xstream package. -
+
XStreamMarshaller The XStreamMarshaller 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 alias map, which consists of string aliases mapped to classes: - Additionally, you can register - custom converters to make sure that only your supported classes can be unmarshalled. + Additionally, you can register + custom converters to make sure that only your supported classes can be unmarshalled. diff --git a/src/reference/docbook/portlet.xml b/src/reference/docbook/portlet.xml index 538b9dca79..adaf47fcdf 100644 --- a/src/reference/docbook/portlet.xml +++ b/src/reference/docbook/portlet.xml @@ -1,20 +1,24 @@ - + 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"> Portlet MVC Framework -
+
Introduction JSR-168 The Java Portlet Specification For more general information about portlet development, please review a whitepaper from Sun entitled - "Introduction to JSR 168", + "Introduction to JSR 168", and of course the - JSR-168 Specification itself. + JSR-168 Specification itself. In addition to supporting conventional (servlet-based) Web development, @@ -78,7 +82,7 @@ DispatcherPortlet exposes the current locale in the same way as DispatcherServlet. -
+
Controllers - The C in MVC The default handler is still a very simple Controller interface, offering just two @@ -98,7 +102,7 @@ same as in the servlet framework.
-
+
Views - The V in MVC 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.
-
+
Web-scoped beans Spring Portlet MVC supports beans whose lifecycle is scoped to the current HTTP request or HTTP Session (both @@ -118,7 +122,7 @@ container(s) that Spring Portlet MVC uses. These bean scopes are described in detail in
- +
-
+
The <classname>DispatcherPortlet</classname> 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. - +
Special beans in the <interfacename>WebApplicationContext</interfacename> @@ -291,7 +295,7 @@ by adding context parameters in the portlet.xml file or portlet init-parameters. The possibilities are listed below. -
+
<classname>DispatcherPortlet</classname> initialization parameters @@ -340,7 +344,7 @@
-
+
The <classname>ViewRendererServlet</classname> The rendering process in Portlet MVC is a bit more complex than in @@ -405,7 +409,7 @@
-
+
Controllers 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. -
+
<classname>AbstractController</classname> and <classname>PortletContentGenerator</classname> Of course, just a Controller @@ -458,7 +462,7 @@ ApplicationContext and control over caching. - +
Features offered by the <classname>AbstractController</classname> @@ -566,7 +570,7 @@ public class SampleController extends AbstractController { controller working. -
+
Other simple controllers Although you can extend AbstractController, @@ -584,7 +588,7 @@ public class SampleController extends AbstractController { then it uses "view" as the view name.
-
+
Command Controllers Spring Portlet MVC has the exact same hierarchy of @@ -646,7 +650,7 @@ public class SampleController extends AbstractController { start using them.
-
+
<classname>PortletWrappingController</classname> Instead of developing new controllers, it is possible to use @@ -673,7 +677,7 @@ public class SampleController extends AbstractController {
-
+
Handler mappings Using a handler mapping you can map incoming portlet requests to @@ -747,7 +751,7 @@ public class SampleController extends AbstractController { Handlers. -
+
<classname>PortletModeHandlerMapping</classname> This is a simple handler mapping that maps incoming requests @@ -765,7 +769,7 @@ public class SampleController extends AbstractController { ]]>
-
+
<classname>ParameterHandlerMapping</classname> If we need to navigate around to multiple controllers without @@ -791,7 +795,7 @@ public class SampleController extends AbstractController { ]]>
-
+
<classname>PortletModeParameterHandlerMapping</classname> 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.
-
+
Adding <interfacename>HandlerInterceptor</interfacename>s 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.
-
+
<classname>HandlerInterceptorAdapter</classname> As with the servlet package, the portlet package has a @@ -892,7 +896,7 @@ public class SampleController extends AbstractController {
-
+
<classname>ParameterMappingInterceptor</classname> The portlet package also has a concrete interceptor named @@ -920,7 +924,7 @@ public class SampleController extends AbstractController {
-
+
Views and resolving them As mentioned previously, Spring Portlet MVC directly reuses all @@ -960,7 +964,7 @@ public class SampleController extends AbstractController { that they work in servlet views.
-
+
Multipart (file upload) support Spring Portlet MVC has built-in multipart support to handle file @@ -970,7 +974,7 @@ public class SampleController extends AbstractController { in the org.springframework.web.portlet.multipart package. Spring provides a PortletMultipartResolver for use with - Commons FileUpload. + Commons FileUpload. How uploading files is supported will be described in the rest of this section. 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. -
+
Using the <interfacename>PortletMultipartResolver</interfacename> The following example shows how to use the @@ -1033,7 +1037,7 @@ public class SampleController extends AbstractController { RenderRequest.
-
+
Handling a file upload in a form After the @@ -1230,7 +1234,7 @@ public class FileUploadBean {
-
+
Handling exceptions Just like Servlet MVC, Portlet MVC provides @@ -1243,7 +1247,7 @@ public class FileUploadBean { to a view name.
-
+
Annotation-based controller configuration 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. - - + + --> The following sections document these annotations and how they are most commonly used in a Portlet environment. -
+
Setting up the dispatcher for annotation support @RequestMapping will only be processed @@ -1311,7 +1315,7 @@ public class FileUploadBean { specifying a custom WebBindingInitializer (see below).
-
+
Defining a controller with <interfacename>@Controller</interfacename> @@ -1358,7 +1362,7 @@ public class FileUploadBean {
-
+
Mapping requests with <interfacename>@RequestMapping</interfacename> @@ -1439,7 +1443,7 @@ public class PetSitesEditController { }
-
+
Supported handler method arguments Handler methods which are annotated with @@ -1587,7 +1591,7 @@ public class PetSitesEditController {
-
+
Binding request parameters to method parameters with <classname>@RequestParam</classname> @@ -1620,7 +1624,7 @@ public class PetSitesEditController { @RequestParam(value="id", required=false)).
-
+
Providing a link to data from the model with <classname>@ModelAttribute</classname> @@ -1680,7 +1684,7 @@ public class PetSitesEditController { }
-
+
Specifying attributes to store in a Session with <classname>@SessionAttributes</classname> @@ -1703,7 +1707,7 @@ public class PetSitesEditController {
-
+
Customizing <classname>WebDataBinder</classname> initialization @@ -1713,7 +1717,7 @@ public class PetSitesEditController { controller or externalize your configuration by providing a custom WebBindingInitializer. -
+
Customizing data binding with <interfacename>@InitBinder</interfacename> @@ -1754,7 +1758,7 @@ public class MyFormController { }
-
+
Configuring a custom <interfacename>WebBindingInitializer</interfacename> @@ -1768,7 +1772,7 @@ public class MyFormController {
-
+
Portlet application deployment The process of deploying a Spring Portlet MVC application is no diff --git a/src/reference/docbook/preface.xml b/src/reference/docbook/preface.xml index 1ba9be14af..0f7d5388f4 100644 --- a/src/reference/docbook/preface.xml +++ b/src/reference/docbook/preface.xml @@ -1,8 +1,12 @@ - + 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"> Preface Developing software applications is hard enough even with good tools @@ -33,6 +37,6 @@ This document provides a reference guide to Spring's features. If you have any requests or comments, please add an issue at - . + . diff --git a/src/reference/docbook/remoting.xml b/src/reference/docbook/remoting.xml index a31ea543f6..53945ea00e 100644 --- a/src/reference/docbook/remoting.xml +++ b/src/reference/docbook/remoting.xml @@ -1,11 +1,15 @@ - + 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"> Remoting and web services using Spring -
+
Introduction Spring features integration classes for remoting support using @@ -102,7 +106,7 @@ public class AccountServiceImpl implements AccountService { public void insertAccount(Account acc) { // do something... } - + public List<Account> getAccounts(String name) { // do something... } @@ -113,7 +117,7 @@ public class AccountServiceImpl implements AccountService { show an example using Hessian as the protocol.
-
+
Exposing services using RMI 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. -
+
Exporting the service using the <classname>RmiServiceExporter</classname> @@ -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"/> - <!-- defaults to 1099 --> + <!-- defaults to 1099 --> <property name="registryPort" value="1199"/> </bean> @@ -169,7 +173,7 @@ public class AccountServiceImpl implements AccountService {
-
+
Linking in the service at the client Our client is a simple object using the @@ -208,14 +212,14 @@ public class AccountServiceImpl implements AccountService {
-
+
Using Hessian or Burlap to remotely call services via HTTP Hessian offers a binary HTTP-based remoting protocol. It is developed by Caucho and more information about Hessian itself can be found - at . + at . -
+
Wiring up the <classname>DispatcherServlet</classname> for Hessian and co. @@ -254,7 +258,7 @@ public class AccountServiceImpl implements AccountService { this case.
-
+
Exposing your beans by using the <classname>HessianServiceExporter</classname> @@ -307,7 +311,7 @@ public class AccountServiceImpl implements AccountService { </servlet-mapping>
-
+
Linking in the service on the client Using the HessianProxyFactoryBean we can @@ -327,7 +331,7 @@ public class AccountServiceImpl implements AccountService { </bean>
-
+
Using Burlap We won't discuss Burlap, the XML-based equivalent of Hessian, in @@ -337,7 +341,7 @@ public class AccountServiceImpl implements AccountService { set to go.
-
+
Applying HTTP basic authentication to a service exposed through Hessian or Burlap @@ -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> @@ -367,13 +371,13 @@ public class AccountServiceImpl implements AccountService { 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 . + a look at the Spring Security project at .
-
+
Exposing services using HTTP invokers As opposed to Burlap and Hessian, which are both lightweight @@ -387,11 +391,11 @@ public class AccountServiceImpl implements AccountService { Under the hood, Spring uses either the standard facilities provided by J2SE to perform HTTP calls or Commons HttpClient. Use the latter if you need more - advanced and easy-to-use functionality. Refer to jakarta.apache.org/commons/httpclient + advanced and easy-to-use functionality. Refer to jakarta.apache.org/commons/httpclient for more info. -
+
Exposing the service object Setting up the HTTP invoker infrastructure for a service object @@ -445,13 +449,13 @@ public class AccountServiceImpl implements AccountService { You can configure the SimpleHttpServerFactoryBean together with a SimpleHttpInvokerServiceExporter as is shown in this example: - <bean name="accountExporter" + <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 {
-
+
Linking in the service at the client Again, linking in the service from the client much resembles the @@ -490,7 +494,7 @@ public class AccountServiceImpl implements AccountService {
-
+
Web services Spring provides full support for standard Java web services @@ -533,13 +537,13 @@ public class AccountServiceImpl implements AccountService { In addition to stock support for JAX-RPC and JAX-WS in Spring Core, - the Spring portfolio also features Spring Web - Services, a solution for contract-first, document-driven web + the Spring portfolio also features Spring Web + Services, a solution for contract-first, document-driven web services - highly recommended for building modern, future-proof web services. -
+
Exposing servlet-based web services using JAX-RPC Spring provides a convenience base class for JAX-RPC servlet @@ -566,7 +570,7 @@ public class AccountServiceImpl implements AccountService { */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.
-
+
Accessing web services using JAX-RPC Spring provides two factory beans to create JAX-RPC web service @@ -641,11 +645,11 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re 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 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.
-
+
Registering JAX-RPC Bean Mappings To transfer complex objects over the wire such as @@ -733,7 +737,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re }
-
+
Registering your own JAX-RPC Handler In this section we will register our own @@ -793,7 +797,7 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re </bean>
-
+
Exposing servlet-based web services using JAX-WS 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.
-
+
Exporting standalone web services using JAX-WS The built-in JAX-WS provider that comes with Sun's JDK 1.6 @@ -903,7 +907,7 @@ public class AccountServiceEndpoint { }
-
+
Exporting web services using the JAX-WS RI's Spring support @@ -925,12 +929,12 @@ public class AccountServiceEndpoint { beans (through the use of @Autowired, as shown above). - Check out https://jax-ws-commons.dev.java.net/spring/ + Check out https://jax-ws-commons.dev.java.net/spring/ for the details on setup and usage style.
-
+
Accessing web services using JAX-WS Analogous to the JAX-RPC support, Spring provides two factory @@ -995,7 +999,7 @@ public class AccountServiceEndpoint {
-
+
JMS It is also possible to expose services transparently using JMS as @@ -1050,7 +1054,7 @@ public class SimpleCheckingAccountService implements CheckingAccountService { </beans> -
+
Server-side configuration On the server, you just need to expose the service object using @@ -1091,7 +1095,7 @@ public class Server { }
-
+
Client-side configuration The client merely needs to create a client-side proxy that will @@ -1130,18 +1134,18 @@ public class Client { service.cancelAccount(new Long(10)); } } -
- You may also wish to investigate the support provided by the Lingo project, which (to quote + You may also wish to investigate the support provided by the Lingo project, which (to quote the homepage blurb) ... is a lightweight POJO based remoting and messaging library based on the Spring Framework's remoting libraries which extends it to support JMS. +
-
+
Auto-detection is not implemented for remote interfaces The main reason why auto-detection of implemented interfaces does @@ -1166,7 +1170,7 @@ public class Client { controlled exposure of specific methods.
-
+
Considerations when choosing a technology Each and every technology presented here has its drawbacks. You @@ -1209,7 +1213,7 @@ public class Client { in third-party or custom solutions here.
-
+
Accessing RESTful services on the Client The RestTemplate is the core class for @@ -1232,7 +1236,7 @@ public class Client { RestTemplate and its associated HttpMessageConverters. -
+
RestTemplate Invoking RESTful services in Java is typically done using a helper @@ -1274,63 +1278,63 @@ if (HttpStatus.SC_CREATED == post.getStatusCode()) { DELETE - delete + delete GET - getForObject + getForObject - getForEntity + getForEntity HEAD - headForHeaders(String - url, String… urlVariables) + headForHeaders(String + url, String… urlVariables) OPTIONS - optionsForAllow(String - url, String… urlVariables) + optionsForAllow(String + url, String… urlVariables) POST - postForLocation(String - url, Object request, String… urlVariables) + postForLocation(String + url, Object request, String… urlVariables) - postForObject(String - url, Object request, Class<T> responseType, String… - uriVariables) + postForObject(String + url, Object request, Class<T> responseType, String… + uriVariables) PUT - put(String - url, Object request, String…urlVariables) + put(String + url, Object request, String…urlVariables) @@ -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 RestClientException will be thrown; this behavior can be changed by plugging in another ResponseErrorHandler - implementation into the RestTemplate. + implementation into the RestTemplate. 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()) { SourceHttpMessageConverter. You can override these defaults using the messageConverters() bean property as would be required if using the - MarshallingHttpMessageConverter or + MarshallingHttpMessageConverter or MappingJackson2HttpMessageConverter. 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. -
+
Working with the URI For each of the main HTTP methods, the RestTemplate provides variants that either take a String URI or java.net.URI as the first argument. - + The String URI variants accept template arguments as a String variable length argument or as a Map<String,String>. - 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: - + restTemplate.getForObject("http://example.com/hotel list", String.class); - + will perform a GET on http://example.com/hotel%20list. - That means if the input URL String is already encoded, it will be encoded twice -- - i.e. http://example.com/hotel%20list will become - http://example.com/hotel%2520list. - 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. http://example.com/hotel%20list will become + http://example.com/hotel%2520list. + If this is not the intended effect, use the java.net.URI method variant, which assumes the URL is already encoded is also generally useful if you want to reuse a single (fully expanded) URI multiple times. The UriComponentsBuilder class can be used - to build and encode the URI including support + to build and encode the URI including support for URI templates. For example you can start with a URL String: - - UriComponents uriComponents = + + UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build() .expand("42", "21") .encode(); - + URI uri = uriComponents.toUri(); Or specify each URI component individually: - - UriComponents uriComponents = + + UriComponents uriComponents = UriComponentsBuilder.newInstance() .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build() .expand("42", "21") .encode(); URI uri = uriComponents.toUri(); - +
-
+
Dealing with request and response headers Besides the methods described above, the RestTemplate @@ -1493,7 +1497,7 @@ URI uri = uriComponents.toUri(); used for arbitrary HTTP method execution based on the HttpEntity class. - Perhaps most importantly, the exchange() + Perhaps most importantly, the exchange() method can be used to add request headers and read response headers. For example: @@ -1513,7 +1517,7 @@ String body = response.getBody();
-
+
HTTP Message Conversion Objects passed to and returned from the methods @@ -1557,7 +1561,7 @@ String body = response.getBody(); can be overridden by setting the supportedMediaTypes bean property -
+
StringHttpMessageConverter An HttpMessageConverter @@ -1568,7 +1572,7 @@ String body = response.getBody(); text/plain.
-
+
FormHttpMessageConverter An HttpMessageConverter @@ -1579,7 +1583,7 @@ String body = response.getBody(); String>.
-
+
ByteArrayHttpMessageConverter An HttpMessageConverter @@ -1592,7 +1596,7 @@ String body = response.getBody(); overriding getContentType(byte[]).
-
+
MarshallingHttpMessageConverter An HttpMessageConverter @@ -1606,22 +1610,22 @@ String body = response.getBody(); this converter supports (text/xml) and (application/xml).
- -
+ +
MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter with Jackson 1.x) - - An HttpMessageConverter - implementation that can read and write JSON using Jackson's - ObjectMapper. JSON mapping can be - customized as needed through the use of Jackson's provided annotations. When - further control is needed, a custom - ObjectMapper can be injected through - the ObjectMapper property for cases where custom - JSON serializers/deserializers need to be provided for specific types. + + An HttpMessageConverter + implementation that can read and write JSON using Jackson's + ObjectMapper. JSON mapping can be + customized as needed through the use of Jackson's provided annotations. When + further control is needed, a custom + ObjectMapper can be injected through + the ObjectMapper property for cases where custom + JSON serializers/deserializers need to be provided for specific types. By default this converter supports (application/json).
-
+
SourceHttpMessageConverter An HttpMessageConverter @@ -1634,7 +1638,7 @@ String body = response.getBody(); (application/xml).
-
+
BufferedImageHttpMessageConverter An HttpMessageConverter diff --git a/src/reference/docbook/resources.xml b/src/reference/docbook/resources.xml index 9d0ce92791..9ccd6d8550 100644 --- a/src/reference/docbook/resources.xml +++ b/src/reference/docbook/resources.xml @@ -1,29 +1,33 @@ - + 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"> Resources -
+
Introduction Java's standard java.net.URL 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 URL implementation - that may be used to access a resource that needs to be obtained from - the classpath, or relative to a - ServletContext. While it is possible + there is no standardized URL implementation + that may be used to access a resource that needs to be obtained from + the classpath, or relative to a + ServletContext. While it is possible to register new handlers for specialized URL - prefixes (similar to existing handlers for prefixes such as - http:), this is generally quite complicated, and the - URL interface still lacks some desirable + prefixes (similar to existing handlers for prefixes such as + http:), this is generally quite complicated, and the + URL interface still lacks some desirable functionality, such as a method to check for the existence of the - resource being pointed to. + resource being pointed to.
-
+
The <interfacename>Resource</interfacename> interface Spring's Resource interface is meant @@ -122,14 +126,14 @@ URL to do its work.
-
+
Built-in <interfacename>Resource</interfacename> implementations There are a number of Resource implementations that come supplied straight out of the box in Spring: -
+
<classname>UrlResource</classname> The UrlResource wraps a @@ -156,7 +160,7 @@ URL string, and will create a UrlResource.
-
+
<classname>ClassPathResource</classname> This class represents a resource which should be obtained from the @@ -182,7 +186,7 @@ ClassPathResource in that case.
-
+
<classname>FileSystemResource</classname> This is a Resource implementation @@ -191,7 +195,7 @@ URL.
-
+
<classname>ServletContextResource</classname> This is a Resource implementation @@ -207,7 +211,7 @@ conceivable) is actually dependent on the Servlet container.
-
+
<classname>InputStreamResource</classname> A Resource implementation for a @@ -226,7 +230,7 @@ need to read a stream multiple times.
-
+
<classname>ByteArrayResource</classname> This is a Resource implementation @@ -240,7 +244,7 @@
-
+
The <interfacename>ResourceLoader</interfacename> The ResourceLoader interface is meant @@ -295,7 +299,7 @@ Strings to Resources: -
+
Resource strings @@ -357,7 +361,7 @@
-
+
The <interfacename>ResourceLoaderAware</interfacename> interface The ResourceLoaderAware interface is @@ -408,7 +412,7 @@ see .
-
+
<literal>Resources</literal> as dependencies If the bean itself is going to determine and supply the resource @@ -429,8 +433,8 @@ myBean has a template property of type Resource, it can be configured with a simple string for that resource, as follows: - - + + ]]> @@ -454,10 +458,10 @@ ]]>
-
+
Application contexts and <interfacename>Resource</interfacename> paths -
+
Constructing application contexts An application context constructor (for a specific application @@ -498,7 +502,7 @@ subsequently used as a ResourceLoader, any unprefixed paths will still be treated as filesystem paths. -
+
Constructing <classname>ClassPathXmlApplicationContext</classname> instances - shortcuts The ClassPathXmlApplicationContext @@ -533,7 +537,7 @@
-
+
Wildcards in application context constructor resource paths The resource paths in application context constructor values may @@ -559,7 +563,7 @@ Resource, as a resource points to just one resource at a time. -
+
Ant-style Patterns When the path location contains an Ant-style pattern, for example: @@ -581,12 +585,12 @@ parses the jar URL and then traverses the contents of the jar file to resolve the wildcards. -
+
Implications on portability If the specified path is already a file URL (either explicitly, or implicitly because the base - ResourceLoader is a + ResourceLoader is a filesystem one, then wildcarding is guaranteed to work in a completely portable fashion. @@ -613,7 +617,7 @@
-
+
The <literal>classpath*:</literal> prefix When constructing an XML-based application context, a location @@ -655,7 +659,7 @@ strategy described above is used for the wildcard subpath.
-
+
Other notes relating to wildcards Please note that "classpath*:" when @@ -669,17 +673,17 @@ returns file system locations for a passed-in empty string (indicating potential roots to search). - Ant-style patterns with "classpath:" - 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 + Ant-style patterns with "classpath:" + 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 may be in only one location, but when a path such as - + is used to try to resolve it, the resolver will work off the (first) URL returned by getResource("com/mycompany");. If this base package node exists in multiple classloader locations, the @@ -690,7 +694,7 @@
-
+
<classname>FileSystemResource</classname> caveats A FileSystemResource that is not attached @@ -731,10 +735,10 @@ ctx.getResource("/some/resource/path/myTemplate.txt");]]> the use of a UrlResource, by using the file: URL prefix. - // actual context type doesn't matter, the Resource will always be UrlResource// actual context type doesn't matter, the Resource will always be UrlResource - // force this FileSystemXmlApplicationContext to load its definition via a UrlResource// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
diff --git a/src/reference/docbook/scheduling.xml b/src/reference/docbook/scheduling.xml index dab9706a73..f93817f3e7 100644 --- a/src/reference/docbook/scheduling.xml +++ b/src/reference/docbook/scheduling.xml @@ -1,11 +1,15 @@ - + 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"> Task Execution and Scheduling -
+
Introduction The Spring Framework provides abstractions for asynchronous @@ -20,8 +24,8 @@ Spring also features integration classes for supporting scheduling with the Timer, part of the JDK since 1.3, and the - Quartz Scheduler (). Both of those + Quartz Scheduler (). Both of those schedulers are set up using a FactoryBean with optional references to Timer or Trigger instances, respectively. Furthermore, a @@ -31,7 +35,7 @@ MethodInvokingFactoryBean operation).
-
+
The Spring <interfacename>TaskExecutor</interfacename> abstraction @@ -61,7 +65,7 @@ behavior, it is possible to use this abstraction for your own needs. -
+
<interfacename>TaskExecutor</interfacename> types There are a number of pre-built implementations of @@ -80,7 +84,7 @@ pooling, keep scrolling further down the page. - + SyncTaskExecutor This implementation doesn't execute invocations @@ -89,7 +93,7 @@ isn't necessary such as simple test cases. - + ConcurrentTaskExecutor This implementation is a wrapper for a Java 5 @@ -104,7 +108,7 @@ alternative. - + SimpleThreadPoolTaskExecutor This implementation is actually a subclass of Quartz's @@ -114,7 +118,7 @@ components. - + ThreadPoolTaskExecutor @@ -169,7 +173,7 @@
-
+
Using a <interfacename>TaskExecutor</interfacename> Spring's TaskExecutor @@ -230,7 +234,7 @@ public class TaskExecutorExample {
-
+
The Spring <interfacename>TaskScheduler</interfacename> abstraction @@ -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. -
+
The <interfacename>Trigger</interfacename> interface The Trigger interface is @@ -301,7 +305,7 @@ public class TaskExecutorExample { }
-
+
<interfacename>Trigger</interfacename> implementations Spring provides two implementations of the @@ -330,7 +334,7 @@ public class TaskExecutorExample { externally.
-
+
<interfacename>TaskScheduler</interfacename> implementations @@ -357,14 +361,14 @@ public class TaskExecutorExample {
-
+
Annotation Support for Scheduling and Asynchronous Execution Spring provides annotation support for both task scheduling and asynchronous method execution. -
+
Enable scheduling annotations @@ -403,7 +407,7 @@ public class AppConfig { with @Scheduled.
-
+
The @Scheduled Annotation The @Scheduled annotation can be added to a method along with @@ -462,7 +466,7 @@ public void doSomething() {
-
+
The @Async Annotation The @Async annotation can be @@ -533,7 +537,7 @@ public class SampleBeanInititalizer { }
-
+
Executor qualification with @Async By default when specifying @Async on @@ -557,7 +561,7 @@ void doSomething(String s) {
-
+
The Task Namespace Beginning with Spring 3.0, there is an XML namespace for configuring @@ -565,7 +569,7 @@ void doSomething(String s) { TaskScheduler instances. It also provides a convenient way to configure tasks to be scheduled with a trigger. -
+
The 'scheduler' element The following element will create a @@ -581,7 +585,7 @@ void doSomething(String s) { are no other configuration options for the scheduler.
-
+
The 'executor' element 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 ThreadPoolExecutor. + consult the documentation for ThreadPoolExecutor. 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"/>
-
+
The 'scheduled-tasks' element The most powerful feature of Spring's task namespace is the @@ -699,18 +703,18 @@ void doSomething(String s) {
-
+
Using the Quartz Scheduler Quartz uses Trigger, Job and JobDetail objects to realize scheduling of all kinds of jobs. For the basic concepts behind - Quartz, have a look at . For convenience + Quartz, have a look at . For convenience purposes, Spring offers a couple of classes that simplify the usage of Quartz within Spring-based applications. -
+
Using the JobDetailBean JobDetail 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 { // do the actual work } @@ -768,7 +772,7 @@ public class ExampleJob extends QuartzJobBean { exampleJob).
-
+
Using the <classname>MethodInvokingJobDetailFactoryBean</classname> @@ -786,9 +790,9 @@ public class ExampleJob extends QuartzJobBean { method (see below): public class ExampleBusinessObject { - + // properties and collaborators - + public void doIt() { // do the actual work } @@ -827,7 +831,7 @@ public class ExampleJob extends QuartzJobBean {
-
+
Wiring up jobs using triggers and the <classname>SchedulerFactoryBean</classname> @@ -879,13 +883,13 @@ public class ExampleJob extends QuartzJobBean { More properties are available for the SchedulerFactoryBean for you to set, such as the calendars used by the job details, properties to customize Quartz with, - etc. Have a look at the SchedulerFactoryBean - Javadoc for more information. + etc. Have a look at the SchedulerFactoryBean + Javadoc for more information.
-
+
Using JDK Timer support 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 TimerFactoryBean. -
+
Creating custom timers Using the TimerTask you can create customer @@ -902,11 +906,11 @@ public class ExampleJob extends QuartzJobBean { public class CheckEmailAddresses extends TimerTask { private List emailAddresses; - + public void setEmailAddresses(List emailAddresses) { this.emailAddresses = emailAddresses; } - + public void run() { // iterate over all email addresses and archive them } @@ -937,7 +941,7 @@ public class ExampleJob extends QuartzJobBean { value).
-
+
Using the <classname>MethodInvokingTimerTaskFactoryBean</classname> @@ -955,9 +959,9 @@ public class ExampleJob extends QuartzJobBean { below): public class BusinessObject { - + // properties and collaborators - + public void doIt() { // do the actual work } @@ -969,7 +973,7 @@ public class ExampleJob extends QuartzJobBean { method being executed on a fixed schedule.
-
+
Wrapping up: setting up the tasks using the <classname>TimerFactoryBean</classname> diff --git a/src/reference/docbook/spring-form.tld.xml b/src/reference/docbook/spring-form.tld.xml index 0aac4e18a1..a28237adbe 100644 --- a/src/reference/docbook/spring-form.tld.xml +++ b/src/reference/docbook/spring-form.tld.xml @@ -1,64 +1,68 @@ - + 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"> spring-form.tld -
+
Introduction + 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. + Please note that the various tags generated by this form tag library + are compliant with the XHTML-1.0-Strict specification and attendant DTD. + This appendix describes the spring-form.tld tag library. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- 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. - Please note that the various tags generated by this form tag library - are compliant with the XHTML-1.0-Strict specification and attendant DTD. - This appendix describes the spring-form.tld tag library. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
The <literal>checkbox</literal> tag Renders an HTML 'input' tag with type 'checkbox'. @@ -459,10 +463,10 @@
-
+
The <literal>checkboxes</literal> tag Renders multiple HTML 'input' tags with type 'checkbox'. - +
Attributes @@ -902,10 +906,10 @@
-
+
The <literal>errors</literal> tag Renders field errors in an HTML 'span' tag. - +
Attributes @@ -1219,10 +1223,10 @@
-
+
The <literal>form</literal> tag Renders an HTML 'form' tag and exposes a binding path to inner tags for binding. - +
Attributes @@ -1278,7 +1282,7 @@ Name of the model attribute under which the form object is exposed. - Defaults to 'command'. + Defaults to 'command'. @@ -1405,7 +1409,7 @@ Name of the model attribute under which the form object is exposed. - Defaults to 'command'. + Defaults to 'command'. @@ -1622,10 +1626,10 @@
-
+
The <literal>hidden</literal> tag Renders an HTML 'input' tag with type 'hidden' using the bound value. - +
Attributes @@ -1687,10 +1691,10 @@
-
+
The <literal>input</literal> tag Renders an HTML 'input' tag with type 'text' using the bound value. - +
Attributes @@ -2144,10 +2148,10 @@
-
+
The <literal>label</literal> tag Renders a form field label in an HTML 'label' tag. - +
Attributes @@ -2461,10 +2465,10 @@
-
+
The <literal>option</literal> tag Renders a single HTML 'option'. Sets 'selected' as appropriate based on bound value. - +
Attributes @@ -2792,10 +2796,10 @@
-
+
The <literal>options</literal> tag Renders a list of HTML 'option' tags. Sets 'selected' as appropriate based on bound value. - +
Attributes @@ -3137,10 +3141,10 @@
-
+
The <literal>password</literal> tag Renders an HTML 'input' tag with type 'password' using the bound value. - +
Attributes @@ -3608,10 +3612,10 @@
-
+
The <literal>radiobutton</literal> tag Renders an HTML 'input' tag with type 'radio'. - +
Attributes @@ -4009,10 +4013,10 @@
-
+
The <literal>radiobuttons</literal> tag Renders multiple HTML 'input' tags with type 'radio'. - +
Attributes @@ -4452,10 +4456,10 @@
-
+
The <literal>select</literal> tag Renders an HTML 'select' element. Supports databinding to the selected option. - +
Attributes @@ -4895,10 +4899,10 @@
-
+
The <literal>textarea</literal> tag Renders an HTML 'textarea'. - +
Attributes diff --git a/src/reference/docbook/spring.tld.xml b/src/reference/docbook/spring.tld.xml index f06c9418ec..49d89ec433 100644 --- a/src/reference/docbook/spring.tld.xml +++ b/src/reference/docbook/spring.tld.xml @@ -1,59 +1,63 @@ - + 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"> spring.tld -
+
Introduction + 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. + Please note that the various tags generated by this form tag library + are compliant with the XHTML-1.0-Strict specification and attendant DTD. + This appendix describes the spring.tld tag library. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- 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. - Please note that the various tags generated by this form tag library - are compliant with the XHTML-1.0-Strict specification and attendant DTD. - This appendix describes the spring.tld tag library. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
The <literal>bind</literal> tag - 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). - -
+ 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). + +
Attributes @@ -81,7 +85,7 @@ Set HTML escaping for this tag, as boolean value. Overrides - the default HTML escaping setting for the current page. + the default HTML escaping setting for the current page. @@ -110,9 +114,9 @@ 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 + 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 @@ -120,14 +124,14 @@
-
+
The <literal>escapeBody</literal> tag - 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). - - + 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). + +
Attributes @@ -155,7 +159,7 @@ Set HTML escaping for this tag, as boolean value. Overrides the - default HTML escaping setting for the current page. + default HTML escaping setting for the current page. @@ -170,21 +174,21 @@ Set JavaScript escaping for this tag, as boolean value. - Default is false. + Default is false.
-
+
The <literal>hasBindErrors</literal> tag - 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). - - + 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). + +
Attributes @@ -212,7 +216,7 @@ Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. + Overrides the default HTML escaping setting for the current page. @@ -227,21 +231,21 @@ 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. + inspected for errors. If errors are available for this bean, they + will be bound under the 'errors' key.
-
+
The <literal>htmlEscape</literal> tag - Sets default HTML escape value for the current page. - Overrides a "defaultHtmlEscape" context-param in web.xml, if any. - - + Sets default HTML escape value for the current page. + Overrides a "defaultHtmlEscape" context-param in web.xml, if any. + +
Attributes @@ -269,21 +273,21 @@ Set the default value for HTML escaping, to be put - into the current PageContext. + into the current PageContext.
-
+
The <literal>message</literal> tag - 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). - - + 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). + +
Attributes @@ -311,9 +315,9 @@ 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). + (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). @@ -328,7 +332,7 @@ The separator character to be used for splitting the - arguments string value; defaults to a 'comma' (','). + arguments string value; defaults to a 'comma' (','). @@ -343,7 +347,7 @@ The code (key) to use when looking up the message. - If code is not provided, the text attribute will be used. + If code is not provided, the text attribute will be used. @@ -358,7 +362,7 @@ Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. + Overrides the default HTML escaping setting for the current page. @@ -387,12 +391,12 @@ 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. + 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. @@ -407,8 +411,8 @@ 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. + This attribute is only used when var is also set. Possible values are + page, request, session and application. @@ -423,8 +427,8 @@ 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. + could not be found. If both text and code are not set, the tag will + output null. @@ -439,20 +443,20 @@ 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). + request, session or application scope. If not specified, the result + gets outputted to the writer (i.e. typically directly to the JSP).
-
+
The <literal>nestedPath</literal> tag - Sets a nested path to be used by the bind tag's path. - - + Sets a nested path to be used by the bind tag's path. + +
Attributes @@ -480,22 +484,22 @@ Set the path that this tag should apply. E.g. 'customer' - to allow bind paths like 'address.street' rather than - 'customer.address.street'. + to allow bind paths like 'address.street' rather than + 'customer.address.street'.
-
+
The <literal>theme</literal> tag - 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). - - + 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). + +
Attributes @@ -523,9 +527,9 @@ 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). + (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). @@ -540,7 +544,7 @@ The separator character to be used for splitting the - arguments string value; defaults to a 'comma' (','). + arguments string value; defaults to a 'comma' (','). @@ -555,7 +559,7 @@ The code (key) to use when looking up the message. - If code is not provided, the text attribute will be used. + If code is not provided, the text attribute will be used. @@ -570,7 +574,7 @@ Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. + Overrides the default HTML escaping setting for the current page. @@ -613,8 +617,8 @@ 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. + This attribute is only used when var is also set. Possible values are + page, request, session and application. @@ -629,8 +633,8 @@ 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. + could not be found. If both text and code are not set, the tag will + output null. @@ -645,23 +649,23 @@ 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). + request, session or application scope. If not specified, the result + gets outputted to the writer (i.e. typically directly to the JSP).
-
+
The <literal>transform</literal> tag - 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). - - + 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). + +
Attributes @@ -689,7 +693,7 @@ Set HTML escaping for this tag, as boolean value. Overrides - the default HTML escaping setting for the current page. + the default HTML escaping setting for the current page. @@ -704,8 +708,8 @@ 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. + This attribute is only used when var is also set. Possible values are + page, request, session and application. @@ -720,8 +724,8 @@ 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. + to have transformed (for instance a Date). Using the PropertyEditor that + is currently in use by the 'spring:bind' tag. @@ -736,21 +740,21 @@ 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). + request, session or application scope. If not specified, the result gets + outputted to the writer (i.e. typically directly to the JSP).
-
+
The <literal>url</literal> tag - 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. - - + 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. + +
Attributes @@ -777,9 +781,9 @@ true - 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. + 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. @@ -793,8 +797,8 @@ true - Specifies a remote application context path. The default is the - current application context path. + Specifies a remote application context path. The default is the + current application context path. @@ -823,9 +827,9 @@ true - 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. + 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. @@ -840,7 +844,7 @@ Set HTML escaping for this tag, as a boolean value. Overrides the - default HTML escaping setting for the current page. + default HTML escaping setting for the current page. @@ -855,19 +859,19 @@ Set JavaScript escaping for this tag, as a boolean value. - Default is false. + Default is false. - +
-
-
+
+
The <literal>eval</literal> tag - Evaluates a Spring expression (SpEL) and either prints the result or assigns it to a variable. - - + Evaluates a Spring expression (SpEL) and either prints the result or assigns it to a variable. + +
Attributes @@ -923,9 +927,9 @@ true - 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. + 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. @@ -940,7 +944,7 @@ Set HTML escaping for this tag, as a boolean value. Overrides the - default HTML escaping setting for the current page. + default HTML escaping setting for the current page. @@ -955,10 +959,10 @@ Set JavaScript escaping for this tag, as a boolean value. - Default is false. + Default is false. - +
diff --git a/src/reference/docbook/swf-sidebar.xml b/src/reference/docbook/swf-sidebar.xml index ecf7ced626..0d69d2617f 100644 --- a/src/reference/docbook/swf-sidebar.xml +++ b/src/reference/docbook/swf-sidebar.xml @@ -1,7 +1,12 @@ - + Spring Web Flow Spring Web Flow (SWF) aims to be the best solution for the management @@ -18,6 +23,6 @@ that drive business processes. For more information about SWF, consult the - Spring Web Flow website. + Spring Web Flow website. diff --git a/src/reference/docbook/testing.xml b/src/reference/docbook/testing.xml index 5b02f5c7df..6b7094bf70 100644 --- a/src/reference/docbook/testing.xml +++ b/src/reference/docbook/testing.xml @@ -1,11 +1,13 @@ - + + Testing
@@ -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 EasyMock or existing + xl:href="http://www.easymock.org">EasyMock or existing Servlet API mock objects such as MockObjects. + xl:href="http://www.mockobjects.com">MockObjects.
@@ -1358,10 +1360,10 @@ public class MyTest { // static inner Config class @ContextConfiguration public class OrderServiceTest { - + @Configuration static class Config { - + // this bean will be injected into the OrderServiceTest class @Bean public OrderService orderService() { @@ -1370,10 +1372,10 @@ public class OrderServiceTest { return orderService; } } - + @Autowired private OrderService orderService; - + @Test public void testOrderService() { // test the orderService @@ -1862,7 +1864,7 @@ public class TransferServiceTest { Gradle it is important to make sure that the build framework does not fork between tests. For example, if the forkMode + xl:href="http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#forkMode">forkMode for the Maven Surefire plug-in is set to always or pertest, 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 { // this instance will be dependency injected by type - @Autowired + @Autowired private HibernateTitleRepository titleRepository; @Test @@ -2004,9 +2006,9 @@ public class HibernateTitleRepositoryTests { looks like this: <?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"> <!-- this bean will be injected into the HibernateTitleRepositoryTests class --> @@ -2014,7 +2016,7 @@ public class HibernateTitleRepositoryTests { role="bold">com.foo.repository.hibernate.HibernateTitleRepository"> <property name="sessionFactory" ref="sessionFactory"/> </bean> - + <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- configuration elided for brevity --> @@ -2543,32 +2545,32 @@ public class HibernateClinicTests extends AbstractClinicTests { } - JUnit: + JUnit: A programmer-oriented testing framework for Java . Used by the Spring Framework in its test suite. - TestNG: A testing + TestNG: A testing framework inspired by JUnit with added support for Java 5 annotations, test groups, data-driven testing, distributed testing, etc. MockObjects.com: Web + xl:href="http://www.mockobjects.com/">MockObjects.com: Web site dedicated to mock objects, a technique for improving the design of code within test-driven development. "Mock + xl:href="http://en.wikipedia.org/wiki/Mock_Object">"Mock Objects": Article in Wikipedia. - EasyMock: + EasyMock: Java library that provides Mock Objects for interfaces (and objects through the class extension) by generating them on the fly using Java's proxy mechanism. Used @@ -2576,27 +2578,27 @@ public class HibernateClinicTests extends AbstractClinicTests { } - JMock: Library + JMock: Library that supports test-driven development of Java code with mock objects. - Mockito: Java mock + Mockito: Java mock library based on the test spy + xl:href="http://xunitpatterns.com/Test%20Spy.html">test spy pattern. - DbUnit: + DbUnit: 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. - The + The Grinder: Java load testing framework. diff --git a/src/reference/docbook/titlepage/spring-html.xml b/src/reference/docbook/titlepage/spring-html.xml new file mode 100644 index 0000000000..1ddfa98333 --- /dev/null +++ b/src/reference/docbook/titlepage/spring-html.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + <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> diff --git a/src/reference/docbook/titlepage/spring-pdf.xml b/src/reference/docbook/titlepage/spring-pdf.xml new file mode 100644 index 0000000000..b3cdc44e22 --- /dev/null +++ b/src/reference/docbook/titlepage/spring-pdf.xml @@ -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> diff --git a/src/reference/docbook/transaction.xml b/src/reference/docbook/transaction.xml index 4157309719..9ed2f71825 100644 --- a/src/reference/docbook/transaction.xml +++ b/src/reference/docbook/transaction.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="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 -
+
Introduction to Spring Framework transaction management Comprehensive transaction support is among the most compelling @@ -83,7 +87,7 @@
-
+
Advantages of the Spring Framework's transaction support model<!--Renamed section to make it more to the point. TR: OK--> Traditionally, Java EE developers have had two choices for @@ -96,7 +100,7 @@ -
+
Global transactions Global transactions enable you to work with multiple transactional @@ -126,7 +130,7 @@ compelling alternatives for declarative transaction management.
-
+
Local transactions Local transactions are resource-specific, such as a transaction @@ -141,7 +145,7 @@ transactions are invasive to the programming model.
-
+
Spring Framework's consistent programming model 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 Atomikos Transactions and - JOTM are other + Oracle RAC) instead. Standalone transaction managers such as Atomikos Transactions and + JOTM are other options. Of course, you may need other application server capabilities such as Java Message Service (JMS) and J2EE Connector Architecture (JCA). @@ -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. -
-
- 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--> 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--> This is primarily a service provider interface (SPI), although it can be used programmatically from your - application code. Because PlatformTransactionManager is an interface, 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" /> - - <!-- other <bean/> definitions here --> + + <!-- other <bean/> definitions here --> </beans> @@ -470,7 +474,7 @@ TR:REVISED, PLS REVIEW--> versa.
-
+
Synchronizing resources with transactions It should now be clear how you create different transaction @@ -487,7 +491,7 @@ TR:REVISED, PLS REVIEW--> through the relevant PlatformTransactionManager. -
+
High-level synchronization approach 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-->
-
+
Low-level synchronization approach Classes such as DataSourceUtils (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. -
-
+
<classname>TransactionAwareDataSourceProxy</classname> 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
-
+
Declarative transaction management @@ -607,7 +611,7 @@ TR: OK AS IS - it's and additional tool, rarely used, but needs to be documented 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. @@ -680,10 +684,10 @@ TR: REVISED, PLS REVIEW - rewrote this to hoefully make it more clear--> EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this behavior. - -
+
Understanding the Spring Framework's declarative transaction implementation @@ -713,7 +717,7 @@ would be rolled back, not necessarily following the EJB rules--> Conceptually, calling a method on a transactional proxy looks like this... - @@ -728,7 +732,7 @@ TR: OK AS IS. images don't show up in the editor, but they do show up in the gen
-
+
Example of declarative transaction implementation 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. - <!-- from the file 'context.xml' --> + <!-- from the file 'context.xml' --> <?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" + 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/spring-tx-3.0.xsd - http://www.springframework.org/schema/aop + 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/spring-aop-3.0.xsd"> - + <!-- this is the service object that we want to make transactional --> <bean id="fooService" class="x.y.service.DefaultFooService"/> - <!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) --> + <!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) --> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- the transactional semantics... --> <tx:attributes> - <!-- all methods starting with 'get' are read-only --> + <!-- all methods starting with 'get' are read-only --> <tx:method name="get*" read-only="true"/> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*"/> </tx:attributes> </tx:advice> - + <!-- ensure that the above transactional advice runs for any execution - of an operation defined by the FooService interface --> + of an operation defined by the FooService interface --> <aop:config> <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/> </aop:config> - - <!-- don't forget the DataSource --> + + <!-- don't forget the DataSource --> <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> - <!-- similarly, don't forget the PlatformTransactionManager --> + <!-- similarly, don't forget the PlatformTransactionManager --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> - - <!-- other <bean/> definitions here --> + + <!-- other <bean/> definitions here --> </beans> @@ -910,7 +914,7 @@ public class DefaultFooService implements FooService { The above configuration will be used to create a transactional proxy around the object that is created from the - fooService bean definition. The proxy will be configured with the transactional advice, so that when an appropriate method is invoked on the proxy, 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.) - <!-- the Spring container is starting up... --> + <!-- the Spring container is starting up... --> [AspectJInvocationContextExposingAdvisorAutoProxyCreator] - Creating implicit proxy for bean 'fooService' with 0 common interceptors and 1 specific interceptors - <!-- the DefaultFooService is actually proxied --> + <!-- the DefaultFooService is actually proxied --> [JdkDynamicAopProxy] - Creating JDK dynamic proxy for [x.y.service.DefaultFooService] - <!-- ... the insertFoo(..) method is now being invoked on the proxy --> + <!-- ... the insertFoo(..) method is now being invoked on the proxy --> [TransactionInterceptor] - Getting transaction for x.y.service.FooService.insertFoo - <!-- the transactional advice kicks in here... --> + <!-- the transactional advice kicks in here... --> [DataSourceTransactionManager] - Creating new transaction with name [x.y.service.FooService.insertFoo] [DataSourceTransactionManager] - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@a53de4] for JDBC transaction - <!-- the insertFoo(..) method from DefaultFooService throws an exception... --> + <!-- the insertFoo(..) method from DefaultFooService throws an exception... --> [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] - <!-- and the transaction is rolled back (by default, RuntimeException instances cause rollback) --> + <!-- and the transaction is rolled back (by default, RuntimeException instances cause rollback) --> [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) - <!-- AOP infrastructure stack trace elements removed for clarity --> + <!-- AOP infrastructure stack trace elements removed for clarity --> at $Proxy0.insertFoo(Unknown Source) at Boot.main(Boot.java:11)
-
+
Rolling back a declarative transaction 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 Exception as it bubbles up the call stack, and make a determination whether to mark the transaction for - rollback. 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 not result in rollback in the default configuration. You can configure exactly which @@ -1006,8 +1010,7 @@ if the underlying application server infrastructure throws an Error the transact <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> - <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/> + <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/> <tx:method name="*"/> </tx:attributes> </tx:advice> @@ -1021,7 +1024,7 @@ if the underlying application server infrastructure throws an Error the transact <tx:advice id="txAdvice"> <tx:attributes> - <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/> + <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/> <tx:method name="*"/> </tx:attributes> </tx:advice> @@ -1060,7 +1063,7 @@ if the underlying application server infrastructure throws an Error the transact clean POJO-based architecture.
-
+
Configuring different transactional semantics for different beans @@ -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> - <!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --> + <!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --> </beans> @@ -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> - <!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) --> + <!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) --> <bean id="fooService" class="x.y.service.DefaultFooService"/> <!-- this bean will also be transactional, but with totally different transactional settings --> @@ -1168,12 +1171,12 @@ if the underlying application server infrastructure throws an Error the transact </tx:attributes> </tx:advice> - <!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --> + <!-- other transaction infrastructure beans such as a PlatformTransactionManager omitted... --> </beans>
-
+
<literal><tx:advice/></literal> settings This section summarizes the various transactional settings that @@ -1213,7 +1216,7 @@ if the underlying application server infrastructure throws an Error the transact <tx:attributes/> tags are summarized below: - +
<literal><tx:method/></literal> settings @@ -1322,7 +1325,7 @@ if the underlying application server infrastructure throws an Error the transact
-
+
Using <interfacename>@Transactional</interfacename> 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 one line of XML configuration: - <!-- from the file 'context.xml' --> + <!-- from the file 'context.xml' --> <?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"> - + <!-- this is the service object that we want to make transactional --> <bean id="fooService" class="x.y.service.DefaultFooService"/> <!-- enable the configuration of transactional behavior based on annotations --> <tx:annotation-driven transaction-manager="txManager"/> - <!-- a PlatformTransactionManager is still required --> + <!-- a PlatformTransactionManager is still required --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- (this dependency is defined somewhere else) --> <property name="dataSource" ref="dataSource"/> </bean> - - <!-- other <bean/> definitions here --> + + <!-- other <bean/> definitions here --> </beans> @@ -1467,7 +1470,7 @@ public class DefaultFooService implements FooService { order to turn @Transactional into runtime behavior on any kind of method. - +
Annotation driven transaction settings @@ -1599,14 +1602,14 @@ public class DefaultFooService implements FooService { // do something } - // these settings have precedence for this method + // these settings have precedence for this method @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void updateFoo(Foo foo) { // do something } } -
+
<interfacename>@Transactional</interfacename> settings The @Transactional annotation is @@ -1649,7 +1652,7 @@ public class DefaultFooService implements FooService { the @Transactional annotation are summarized in the following table: -
+
<interfacename>@Transactional</interfacename> properties @@ -1668,14 +1671,14 @@ public class DefaultFooService implements FooService { value - + String - + Optional qualifier specifying the transaction manager to be used. - + propagation @@ -1769,8 +1772,8 @@ public class DefaultFooService implements FooService { the name of the transaction would be: com.foo.BusinessService.handlePayment. - -
+ +
Multiple Transaction Managers with <interfacename>@Transactional</interfacename> 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 @Transactional annotation can be used to optionally specify the identity of the PlatformTransactionManager 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 public class TransactionalService { - + @Transactional("order") public void setSomething(String name) { ... } - + @Transactional("account") public void doSomething() { ... } } - + could be combined with the following transaction manager bean declarations in the application context. @@ -1801,16 +1804,16 @@ public class DefaultFooService implements FooService { ... - + ]]> - - In this case, the two methods on TransactionalService will run under separate - transaction managers, differentiated by the "order" and "account" qualifiers. - The default <tx:annotation-driven> target bean name transactionManager will - still be used if no specifically qualified PlatformTransactionManager bean is found. + + In this case, the two methods on TransactionalService will run under separate + transaction managers, differentiated by the "order" and "account" qualifiers. + The default <tx:annotation-driven> target bean name transactionManager will + still be used if no specifically qualified PlatformTransactionManager bean is found.
-
+
Custom shortcut annotations If you find you are repeatedly using the same attributes with @Transactional @@ -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 { - } + } allows us to write the example from the previous section as public class TransactionalService { - + @OrderTx public void setSomething(String name) { ... } - + @AccountTx public void doSomething() { ... } } - - Here we have used the syntax to define the transaction manager qualifier, but could also have + + Here we have used the syntax to define the transaction manager qualifier, but could also have included propagation behavior, rollback rules, timeouts etc. -
+
-
+
Transaction propagation - 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. -
+
Required @@ -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.
-
+
RequiresNew @@ -1928,7 +1931,7 @@ TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section d transaction's rollback status.
-
+
Nested PROPAGATION_NESTED uses a @@ -1943,7 +1946,7 @@ TR: REVISED, PLS REVIEW - changed it back; it's not just settings, the section d
-
+
Advising transactional operations<!--Need better heading? Executing transactional advice? TR: OK AS IS--> Suppose you want to execute both @@ -2010,7 +2013,7 @@ public class SimpleProfiler implements Ordered { this.order = order; } - // this method is the around advice + // this method *is* the around advice 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"/> <aop:config> - <!-- this advice will execute around the transactional advice --> + <!-- this advice will execute around the transactional advice --> <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 { The result of the above configuration is a fooService bean that has profiling and transactional - aspects applied to it in the desired order. You configure any number of additional aspects in similar fashion. @@ -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> - <!-- other <bean/> definitions such as a DataSource and a PlatformTransactionManager here --> + <!-- other <bean/> definitions such as a DataSource and a PlatformTransactionManager here --> </beans> @@ -2143,7 +2146,7 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde You configure additional aspects in similar fashion.
-
+
Using <interfacename>@Transactional</interfacename> with AspectJ @@ -2175,7 +2178,7 @@ TR: REVISED, PLS REVIEW. changed to 'desired'; seems clear that the desired orde // construct an appropriate transaction manager DataSourceTransactionManager txManager = new DataSourceTransactionManager(getDataSource()); -// configure the AnnotationTransactionAspect to use it; this must be done before executing any transactional methods +// configure the AnnotationTransactionAspect to use it; this must be done before executing any transactional methods AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); @@ -2197,15 +2200,15 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); To weave your applications with the AnnotationTransactionAspect you must either build - your application with AspectJ (see the AspectJ - Development Guide) or use load-time weaving. See AspectJ + Development Guide) or use load-time weaving. See for a discussion of load-time weaving with AspectJ.
-
+
Programmatic transaction management The Spring Framework provides two means of programmatic transaction @@ -2229,7 +2232,7 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); UserTransaction API, although exception handling is less cumbersome. -
+
Using the <classname>TransactionTemplate</classname> The TransactionTemplate adopts the same @@ -2261,10 +2264,10 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); public class SimpleService implements Service { - // single TransactionTemplate shared amongst all methods in this instance + // single TransactionTemplate shared amongst all methods in this instance private final TransactionTemplate transactionTemplate; - // use constructor-injection to supply the PlatformTransactionManager + // use constructor-injection to supply the PlatformTransactionManager 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); -
+
Specifying transaction settings You can specify transaction settings such as the propagation @@ -2350,21 +2353,21 @@ AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager); -
- Finally, instances of the - TransactionTemplate class are threadsafe, in that - instances do not maintain any conversational state. - TransactionTemplate instances - do however maintain configuration state, so while a - number of classes may share a single instance of a - TransactionTemplate, if a class needs to use a - TransactionTemplate with different settings (for - example, a different isolation level), then you need to create two - distinct TransactionTemplate instances. + Finally, instances of the + TransactionTemplate class are threadsafe, in that + instances do not maintain any conversational state. + TransactionTemplate instances + do however maintain configuration state, so while a + number of classes may share a single instance of a + TransactionTemplate, if a class needs to use a + TransactionTemplate with different settings (for + example, a different isolation level), then you need to create two + distinct TransactionTemplate instances. +
-
+
Using the <interfacename>PlatformTransactionManager</interfacename> @@ -2394,7 +2397,7 @@ txManager.commit(status);
-
+
Choosing between programmatic and declarative transaction management @@ -2416,7 +2419,7 @@ txManager.commit(status); reduced.
-
+
Application server-specific integration Spring's transaction abstraction generally is application server @@ -2451,7 +2454,7 @@ txManager.commit(status); explicitly; rather, they are chosen automatically, with the standard JtaTransactionManager as default fallback. -
+
IBM WebSphere On WebSphere 6.1.0.9 and above, the recommended Spring JTA @@ -2465,7 +2468,7 @@ txManager.commit(status); IBM!
-
+
BEA WebLogic Server On WebLogic Server 9.0 or above, you typically would use the @@ -2479,7 +2482,7 @@ txManager.commit(status); transactions in all cases.
-
+
Oracle OC4J Spring ships a special adapter class for OC4J 10.1.3 or later @@ -2496,10 +2499,10 @@ txManager.commit(status);
-
+
Solutions to common problems -
+
Use of the wrong transaction manager for a specific <interfacename>DataSource</interfacename> @@ -2521,7 +2524,7 @@ txManager.commit(status);
-
+
Further Resources For more information about the Spring Framework's transaction @@ -2529,18 +2532,18 @@ txManager.commit(status); - Distributed - transactions in Spring, with and without XA is a JavaWorld + Distributed + transactions in Spring, with and without XA 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. - Java - Transaction Design Strategies is a book available from InfoQ that provides a well-paced + Java + Transaction Design Strategies is a book available from InfoQ 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. diff --git a/src/reference/docbook/validation.xml b/src/reference/docbook/validation.xml index de80df0cec..97ae0cdd00 100644 --- a/src/reference/docbook/validation.xml +++ b/src/reference/docbook/validation.xml @@ -1,11 +1,15 @@ - + 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"> Validation, Data Binding, and Type Conversion -
+
Introduction There are pros and cons for considering validation as business logic, @@ -45,7 +49,7 @@ chapter.
-
+
Validation using Spring's <interfacename>Validator</interfacename> interface @@ -92,7 +96,7 @@ /** - * This Validator validates just Person instances + * This Validator validates *just* Person instances *//** - * This Validator validates Customer instances, and any subclasses of Customer too + * This Validator validates Customer instances, and any subclasses of Customer too */
-
+
Resolving codes to error messages We've talked about databinding and validation. Outputting messages @@ -210,14 +214,14 @@ More information on the MessageCodesResolver and the default - strategy can be found online with the Javadocs for MessageCodesResolver and DefaultMessageCodesResolver respectively. + strategy can be found online with the Javadocs for MessageCodesResolver and DefaultMessageCodesResolver respectively.
-
+
Bean manipulation and the <interfacename>BeanWrapper</interfacename> @@ -228,8 +232,8 @@ would have a setter method setBingoMadness(..) and a getter method getBingoMadness(). For more information about JavaBeans and the specification, please refer to Sun's - website ( java.sun.com/products/javabeans). + website ( java.sun.com/products/javabeans). One quite important class in the beans package is the BeanWrapper interface and its corresponding @@ -255,7 +259,7 @@ indicated by its name: it wraps a bean to perform actions on that bean, like setting and retrieving properties. -
+
Setting and getting basic and nested properties 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: -
+
Examples of properties @@ -389,8 +393,8 @@ company.setPropertyValue("managingDirector", jim.getWrappedInstance()); Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]> -
- Built-in <interface>PropertyEditor</interface> + <section xml:id="beans-beans-conversion"> + <title>Built-in <interfacename>PropertyEditor</interfacename> implementations Spring uses the concept of PropertyEditors to @@ -442,7 +446,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]> -
+
Built-in <literal>PropertyEditors</literal> @@ -598,13 +602,13 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]>// the PropertyEditor for the Foo class + FooEditor ]]>// the PropertyEditor for the Foo class Note that you can also use the standard BeanInfo JavaBeans mechanism here as well - (described in not-amazing-detail here). Find below an example of using the + (described in not-amazing-detail here). Find below an example of using the BeanInfo mechanism for explicitly registering one or more PropertyEditor instances with the properties of an associated class. @@ -612,7 +616,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]>// the BeanInfo for the Foo class + FooBeanInfo ]]>// the BeanInfo for the Foo class Here is the Java source code for the referenced FooBeanInfo class. This would associate a @@ -637,7 +641,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]> -
+
Registering additional custom <interfacename>PropertyEditors</interfacename> @@ -725,7 +729,7 @@ public class DependsOnExoticType { The PropertyEditor implementation could look similar to this: - // converts string representation to ExoticType object// converts string representation to ExoticType object ]]> -
+
Using <interfacename>PropertyEditorRegistrars</interfacename> @@ -791,7 +795,7 @@ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegist public void registerCustomEditors(PropertyEditorRegistry registry) { - ]]>// it is expected that new PropertyEditor instances are created// it is expected that new PropertyEditor instances are created// you could register as many custom property editors as are required here...this.customPropertyEditorRegistrar.registerCustomEditors(binder);// other methods to do with registering a User// other methods to do with registering a User This style of PropertyEditor @@ -861,7 +865,7 @@ public final class CustomPropertyEditorRegistrar implements PropertyEditorRegist
-
+
Spring 3 Type Conversion Spring 3 introduces a core.convert 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. -
+
Converter SPI The SPI to implement type conversion logic is simple and strongly @@ -911,7 +915,7 @@ final class StringToInteger implements Converter { }]]>
-
+
ConverterFactory When you need to centralize the conversion logic for an entire @@ -958,7 +962,7 @@ final class StringToEnumConverterFactory implements ConverterFactory
-
+
GenericConverter When you require a sophisticated Converter implementation, consider @@ -1001,7 +1005,7 @@ public interface GenericConverter { type conversion needs. -
+
ConditionalGenericConverter Sometimes you only want a Converter to execute if a specific @@ -1027,7 +1031,7 @@ public interface GenericConverter {
-
+
ConversionService API The ConversionService defines a unified API for executing type @@ -1049,7 +1053,7 @@ public interface ConversionService { }]]> Most ConversionService implementations also implement - ConverterRegistry, which provides an SPI for + ConverterRegistry, which provides an SPI for registering converters. Internally, a ConversionService implementation delegates to its registered converters to carry out type conversion logic. @@ -1062,7 +1066,7 @@ public interface ConversionService { factory for creating common ConversionService configurations.
-
+
Configuring a ConversionService A ConversionService is a stateless object designed to be @@ -1110,7 +1114,7 @@ public interface ConversionService { FormattingConversionServiceFactoryBean.
-
+
Using a ConversionService programmatically To work with a ConversionService instance programmatically, simply @@ -1131,7 +1135,7 @@ public class MyService {
-
+
Spring 3 Field Formatting As discussed in the previous section, -
+
Formatter SPI The Formatter SPI to implement field formatting logic is simple and @@ -1207,8 +1211,8 @@ public interface Parser { datetime package provides a DateFormatter to format java.util.Date objects with a java.text.DateFormat. The datetime.joda package provides comprehensive - datetime formatting support based on the Joda Time library. + datetime formatting support based on the Joda Time library. Consider DateFormatter as an example Formatter implementation: @@ -1246,11 +1250,11 @@ public final class DateFormatter implements Formatter { }]]> The Spring team welcomes community-driven Formatter contributions; - see http://jira.springframework.org to contribute. + see http://jira.springframework.org to contribute.
-
+
Annotation-driven Formatting As you will see, field formatting can be configured by field type @@ -1325,7 +1329,7 @@ public interface AnnotationFormatterFactory { }]]> -
+
Format Annotation API A portable format annotation API exists in the @@ -1346,18 +1350,18 @@ public interface AnnotationFormatterFactory {
-
+
FormatterRegistry SPI - The FormatterRegistry is an SPI for registering formatters and - converters. FormattingConversionService is - an implementation of FormatterRegistry suitable for most environments. - This implementation may be configured programmatically or declaratively - as a Spring bean using - FormattingConversionServiceFactoryBean. - Because this implementation also implements - ConversionService, it can be directly - configured for use with Spring's DataBinder and the Spring Expression + The FormatterRegistry is an SPI for registering formatters and + converters. FormattingConversionService is + an implementation of FormatterRegistry suitable for most environments. + This implementation may be configured programmatically or declaratively + as a Spring bean using + FormattingConversionServiceFactoryBean. + Because this implementation also implements + ConversionService, it can be directly + configured for use with Spring's DataBinder and the Spring Expression Language (SpEL). @@ -1378,24 +1382,24 @@ public interface FormatterRegistry extends ConverterRegistry { }]]> As shown above, Formatters can be registered by fieldType or - annotation. + annotation. 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. - + these rules once and they are applied whenever formatting is needed. +
-
+
FormatterRegistrar SPI - - The FormatterRegistrar is an SPI for registering formatters and - converters through the FormatterRegistry: - - + + The FormatterRegistrar is an SPI for registering formatters and + converters through the FormatterRegistry: + + - 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. - -
- -
+ 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. + +
+ +
Configuring Formatting in Spring MVC In a Spring MVC application, you may configure a custom @@ -1449,7 +1453,7 @@ public interface FormatterRegistrar { classpath. 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: @@ -1487,16 +1491,16 @@ public interface FormatterRegistrar { ]]> - See and - the FormattingConversionServiceFactoryBean - for more information on when to use FormatterRegistrars. - + See and + the FormattingConversionServiceFactoryBean + for more information on when to use FormatterRegistrars. +
-
+
Configuring a global date & time format By default, date and time fields that are not annotated with @@ -1586,7 +1590,7 @@ public class AppConfig { for details.
-
+
Spring 3 Validation 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. -
+
Overview of the JSR-303 Bean Validation API JSR-303 standardizes validation constraint declaration and metadata @@ -1629,16 +1633,16 @@ public class AppConfig { When an instance of this class is validated by a JSR-303 Validator, these constraints will be enforced. - For general information on JSR-303, see the Bean Validation - Specification. For information on the specific capabilities of - the default reference implementation, see the Hibernate Validator + For general information on JSR-303, see the Bean Validation + Specification. For information on the specific capabilities of + the default reference implementation, see the Hibernate Validator documentation. To learn how to setup a JSR-303 implementation as a Spring bean, keep reading.
-
+
Configuring a Bean Validation Implementation 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. -
+
Injecting a Validator LocalValidatorFactoryBean implements both @@ -1695,7 +1699,7 @@ public class MyService { }]]>
-
+
Configuring Custom Constraints 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.
-
+
Additional Configuration Options The default LocalValidatorFactoryBean @@ -1751,7 +1755,7 @@ public class MyConstraintValidator implements ConstraintValidator {
-
+
Configuring a DataBinder Since Spring 3, a DataBinder instance can be configured with a @@ -1776,14 +1780,14 @@ binder.validate(); BindingResult results = binder.getBindingResult();
-
+
Spring MVC 3 Validation 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. -
+
Triggering @Controller Input Validation To trigger validation of a @Controller input, simply annotate the @@ -1803,7 +1807,7 @@ public class MyController {
-
+
Configuring a Validator for use by Spring MVC The Validator instance invoked when a @Valid method argument is @@ -1845,7 +1849,7 @@ public class MyController { ]]>
-
+
Configuring a JSR-303 Validator for use by Spring MVC With JSR-303, a single javax.validation.Validator diff --git a/src/reference/docbook/view.xml b/src/reference/docbook/view.xml index 0aecd42624..94b18964a0 100644 --- a/src/reference/docbook/view.xml +++ b/src/reference/docbook/view.xml @@ -1,11 +1,15 @@ - + 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"> View technologies -
+
Introduction One of the areas in which Spring excels is in the separation of view @@ -18,7 +22,7 @@ framework.
-
+
JSP & JSTL Spring provides a couple of out-of-the-box solutions for JSP and @@ -26,22 +30,22 @@ in the WebApplicationContext. Furthermore, of course you need to write some JSPs that will actually render the view. - + 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 - - How to Reference and Use JSTL in your Web Application provides a + + How to Reference and Use JSTL in your Web Application 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. -
+
View resolvers Just as with any other view technology you're integrating with @@ -51,7 +55,7 @@ ResourceBundleViewResolver. Both are declared in the WebApplicationContext: - <!-- the ResourceBundleViewResolver --> + <!-- the ResourceBundleViewResolver --> <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 be no direct access by clients.
-
+
'Plain-old' JSPs versus JSTL When using the Java Standard Tag Library you must use a special @@ -90,7 +94,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp preparation before things such as the I18N features will work.
-
+
Additional tags facilitating development Spring provides data binding of request parameters to command @@ -106,7 +110,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp the appendix entitled .
-
+
Using Spring's form tag library As of version 2.0, Spring provides a comprehensive set of data @@ -126,7 +130,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp tag is used. We have included generated HTML snippets where certain tags require further commentary. -
+
Configuration The form tag library comes bundled in @@ -143,7 +147,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp want to use for the tags from this library.
-
+
The <literal>form</literal> tag This tag renders an HTML 'form' tag and exposes a binding path @@ -228,17 +232,17 @@ productList.url=/WEB-INF/jsp/productlist.jsp </form:form>
-
+
The <literal>input</literal> tag This tag renders an HTML 'input' tag using the bound value and type='text' by default. For an example of this tag, see . 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.
-
+
The <literal>checkbox</literal> tag This tag renders an HTML 'input' tag with type @@ -287,14 +291,14 @@ productList.url=/WEB-INF/jsp/productlist.jsp <table> <tr> <td>Subscribe to newsletter?:</td> - <%-- Approach 1: Property is of type java.lang.Boolean --%> + <%-- Approach 1: Property is of type java.lang.Boolean --%> <td><form:checkbox path="preferences.receiveNewsletter"/></td> </tr> <tr> <td>Interests:</td> <td> - <%-- Approach 2: Property is of an array or of type java.util.Collection --%> + <%-- Approach 2: Property is of an array or of type java.util.Collection --%> 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 <tr> <td>Favourite Word:</td> <td> - <%-- Approach 3: Property is of type java.lang.Object --%> + <%-- Approach 3: Property is of type java.lang.Object --%> Magic: <form:checkbox path="preferences.favouriteWord" value="Magic"/> </td> </tr> @@ -313,7 +317,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp There are 3 approaches to the checkbox tag which should meet all your checkbox needs. - + Approach One - When the bound value is of type @@ -373,7 +377,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp .
-
+
The <literal>checkboxes</literal> tag This tag renders multiple HTML 'input' tags with type @@ -396,7 +400,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp <tr> <td>Interests:</td> <td> - <%-- Property is of an array or of type java.util.Collection --%> + <%-- Property is of an array or of type java.util.Collection --%> <form:checkboxes path="preferences.interests" items="${interestList}"/> </td> </tr> @@ -412,7 +416,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp using "itemValue" and the label using "itemLabel".
-
+
The <literal>radiobutton</literal> tag This tag renders an HTML 'input' tag with type 'radio'. @@ -427,7 +431,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </tr>
-
+
The <literal>radiobuttons</literal> tag This tag renders multiple HTML 'input' tags with type @@ -450,7 +454,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </tr>
-
+
The <literal>password</literal> tag This tag renders an HTML 'input' tag with type 'password' using @@ -476,7 +480,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </tr>
-
+
The <literal>select</literal> tag This tag renders an HTML 'select' element. It supports data @@ -504,7 +508,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </tr>
-
+
The <literal>option</literal> tag This tag renders an HTML 'option'. It sets 'selected' as @@ -538,7 +542,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </tr>
-
+
The <literal>options</literal> tag This tag renders a list of HTML 'option' tags. It sets the @@ -588,7 +592,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp property will apply to the map value.
-
+
The <literal>textarea</literal> tag This tag renders an HTML 'textarea'. @@ -600,7 +604,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </tr>
-
+
The <literal>hidden</literal> tag This tag renders an HTML 'input' tag with type 'hidden' using @@ -617,7 +621,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp
-
+
The <literal>errors</literal> tag This tag renders field errors in an HTML 'span' tag. It provides @@ -761,7 +765,7 @@ productList.url=/WEB-INF/jsp/productlist.jsp </form>
-
+
HTTP Method Conversion 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) { }
-
+
HTML5 Tags - + Starting with Spring 3, the Spring form tag library allows entering - dynamic attributes, which means you can enter any HTML5 specific attributes. - + dynamic attributes, which means you can enter any HTML5 specific attributes. + 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. - + 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. +
-
+
Tiles It is possible to integrate Tiles - just as any other view @@ -847,7 +851,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) { org.springframework.web.servlet.view.tiles package. -
+
Dependencies 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) {
-
+
How to integrate Tiles 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 ). In Spring this is done using the + Tiles concepts, please have a look at ). In Spring this is done using the TilesConfigurer. Have a look at the following piece of example ApplicationContext configuration: @@ -908,7 +912,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) { find two possibilities, the UrlBasedViewResolver and the ResourceBundleViewResolver. -
+
<classname>UrlBasedViewResolver</classname> @@ -922,7 +926,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) { </bean>
-
+
<classname>ResourceBundleViewResolver</classname> @@ -950,13 +954,13 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp ResourceBundleViewResolver, you can easily mix different view technologies. - Note that the TilesView class for Tiles 2 - supports JSTL (the JSP Standard Tag Library) out of the box, whereas - there is a separate TilesJstlView subclass in the - Tiles 1.x support. + Note that the TilesView class for Tiles 2 + supports JSTL (the JSP Standard Tag Library) out of the box, whereas + there is a separate TilesJstlView subclass in the + Tiles 1.x support.
-
+
<classname>SimpleSpringPreparerFactory</classname> and <classname>SpringBeanPreparerFactory</classname> @@ -1005,18 +1009,18 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
-
+
Velocity & FreeMarker - Velocity and FreeMarker are two templating + Velocity and FreeMarker 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 FreeMarker web site. + differences between the two languages, see the FreeMarker web site. -
+
Dependencies Your web application will need to include velocity-tools-generic-1.x.jar
-
+
Context configuration A suitable configuration is initialized by adding the relevant configurer bean definition to your '*-servlet.xml' as shown below: - <!-- + <!-- 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> -<!-- +<!-- 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> -<!-- +<!-- 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
-
+
Creating templates Your templates need to be stored in the directory specified by the @@ -1105,14 +1109,14 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp appropriate.
-
+
Advanced configuration 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. -
+
velocity.properties This file is completely optional, but if specified, contains the @@ -1142,14 +1146,14 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp </property> </bean> - Refer to the API - documentation for Spring configuration of Velocity, or the + Refer to the API + documentation for Spring configuration of Velocity, or the Velocity documentation for examples and definitions of the 'velocity.properties' file itself.
-
+
FreeMarker FreeMarker 'Settings' and 'SharedVariables' can be passed @@ -1178,7 +1182,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
-
+
Bind support and form handling 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. -
+
The bind macros A standard set of macros are maintained within the @@ -1209,7 +1213,7 @@ findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp respectively.
-
+
Simple binding 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.
-
+
Form input generation macros Additional convenience macros for both languages simplify both @@ -1290,7 +1294,7 @@ recommend sticking to 'spring' --> The following table of available macros show the VTL and FTL definitions and the parameter list that each takes. -
+
Table of macro definitions @@ -1515,7 +1519,7 @@ recommend sticking to 'spring' --> in VTL. Where usage differences exist between the two languages, they are explained in the notes. -
+
Input Fields <!-- the Name field example from above using form macros in VTL --> @@ -1550,7 +1554,7 @@ recommend sticking to 'spring' --> The generated HTML looks like this: 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.
-
+
Selection Fields Four selection field macros can be used to generate common UI @@ -1613,15 +1617,15 @@ recommend sticking to 'spring' --> 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 @@ -1634,7 +1638,7 @@ New York 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 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
-
+
HTML escaping and XHTML compliance Default usage of the form macros above will result in HTML tags @@ -1700,7 +1704,7 @@ New York
-
+
XSLT XSLT is a transformation language for XML and is popular as a view @@ -1710,7 +1714,7 @@ New York an XML document as model data and have it transformed with XSLT in a Spring Web MVC application. -
+
My First Words This example is a trivial Spring application that creates a list @@ -1721,7 +1725,7 @@ New York turn the list of words into a simple XML document ready for transformation. -
+
Bean definitions Configuration is standard for a simple Spring application. The @@ -1734,7 +1738,7 @@ New York ... that encapsulates our word generation logic.
-
+
Standard MVC controller code The controller logic is encapsulated in a subclass of @@ -1744,15 +1748,15 @@ New York 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); } @@ -1771,7 +1775,7 @@ New York tools to manage the domification process.
-
+
Convert the model data to XML In order to create a DOM document from our list of words or any @@ -1822,7 +1826,7 @@ public class HomePage extends AbstractXsltView { request) method instead.
-
+
Defining the view properties The views.properties file (or equivalent xml definition if @@ -1845,7 +1849,7 @@ home.root=words the createXsltSource(..) method(s).
-
+
Document transformation Finally, we have the XSLT code used for transforming the above @@ -1877,7 +1881,7 @@ home.root=words
-
+
Summary A summary of the files discussed and their location in the WAR @@ -1893,7 +1897,7 @@ home.root=words | | | +- xslt | | | - | | +- HomePageController.class + | | +- HomePageController.class | | +- HomePage.class | | | +- views.properties @@ -1915,10 +1919,10 @@ home.root=words
-
+
Document views (PDF/Excel) -
+
Introduction Returning an HTML page isn't always the best way for the user to @@ -1932,7 +1936,7 @@ home.root=words your classpath, and for PDF generation, the iText library.
-
+
Configuration and setup Document based views are handled in an almost identical fashion to @@ -1942,14 +1946,14 @@ home.root=words spreadsheet (which can also be viewed or manipulated in Open Office). -
+
Document view definitions 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: - + home.(class)=xslt.HomePage home.stylesheetLocation=/WEB-INF/xsl/home.xslt home.root=words @@ -1963,7 +1967,7 @@ pdf.(class)=pdf.HomePage as the 'url' property in the view definition
-
+
Controller code The controller code we'll use remains exactly the same from the @@ -1973,7 +1977,7 @@ pdf.(class)=pdf.HomePage at decoupling the views from the controllers!
-
+
Subclassing for Excel views Exactly as we did for the XSLT example, we'll subclass suitable @@ -1988,7 +1992,7 @@ pdf.(class)=pdf.HomePage 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: - + 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 { And the following is a view generating the same Excel file, now using JExcelApi: - + 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.
-
+
Subclassing for PDF views 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))); - + } } @@ -2103,17 +2107,17 @@ public class PDFPage extends AbstractPdfView {
-
+
JasperReports - JasperReports () is a powerful + JasperReports () 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. -
+
Dependencies Your application will need to include the latest release of @@ -2153,7 +2157,7 @@ public class PDFPage extends AbstractPdfView { JasperReports also requires a JAXP compliant XML parser.
-
+
Configuration 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. -
+
Configuring the <interfacename>ViewResolver</interfacename> @@ -2181,7 +2185,7 @@ public class PDFPage extends AbstractPdfView { the next section.)
-
+
Configuring the <literal>View</literal>s 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: -
+
JasperReports <interfacename>View</interfacename> classes @@ -2258,7 +2262,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper the underlying report file. -
+
About Report Files JasperReports has two distinct types of report file: the design @@ -2276,7 +2280,7 @@ simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper restart your application.
-
+
Using <classname>JasperReportsMultiFormatView</classname> @@ -2317,7 +2321,7 @@ HttpServletResponse response) throws Exception { By default the following mapping key mappings are configured in JasperReportsMultiFormatView: -
+
<classname>JasperReportsMultiFormatView</classname> Default Mapping Key Mappings @@ -2370,7 +2374,7 @@ HttpServletResponse response) throws Exception { -
+
Populating the <classname>ModelAndView</classname> In order to render your report correctly in the format you have @@ -2429,7 +2433,7 @@ simpleReport.reportDataKey=myBeanData second approach.
-
+
Working with Sub-Reports JasperReports provides support for embedded sub-reports within @@ -2442,7 +2446,7 @@ simpleReport.reportDataKey=myBeanData configure sub-reports declaratively, and you can include additional data for these sub-reports directly from your controllers. -
+
Configuring Sub-Report Files To control which sub-report files are included in a master @@ -2487,7 +2491,7 @@ simpleReport.reportDataKey=myBeanData the JasperReports engine under the given key.
-
+
Configuring Sub-Report Data Sources This step is entirely optional when using Spring to configure your @@ -2508,7 +2512,7 @@ simpleReport.reportDataKey=myBeanData
-
+
Configuring Exporter Parameters If you have special requirements for exporter configuration -- @@ -2544,14 +2548,14 @@ simpleReport.reportDataKey=myBeanData
-
+
Feed Views Both AbstractAtomFeedView and AbstractRssFeedView inherit from the base class AbstractFeedView and are used to provide Atom and - RSS Feed views respectfully. They are based on java.net's ROME project and are located in + RSS Feed views respectfully. They are based on java.net's ROME project and are located in the package org.springframework.web.servlet.view.feed. @@ -2604,11 +2608,11 @@ simpleReport.reportDataKey=myBeanData written to the response object after the method returns. For an example of creating an Atom view please refer to Alef - Arendsen's SpringSource Team Blog entry. + Arendsen's SpringSource Team Blog entry.
-
+
XML Marshalling View The MarhsallingView uses an XML @@ -2624,28 +2628,28 @@ simpleReport.reportDataKey=myBeanData chapter Marshalling XML using O/X Mappers.
- -
- JSON Mapping View - + +
+ JSON Mapping View + The MappingJackson2JsonView (or MappingJacksonJsonView depending on the the Jackson version you have) uses the Jackson - library's ObjectMapper 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 RenderedAttributes - property. The extractValueFromSingleKeyModel 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. + library's ObjectMapper 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 RenderedAttributes + property. The extractValueFromSingleKeyModel 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. + + JSON mapping can be customized as needed through the use of Jackson's provided + annotations. When further control is needed, a custom + ObjectMapper can be injected through the + ObjectMapper property for cases where custom JSON + serializers/deserializers need to be provided for specific types. - JSON mapping can be customized as needed through the use of Jackson's provided - annotations. When further control is needed, a custom - ObjectMapper can be injected through the - ObjectMapper property for cases where custom JSON - serializers/deserializers need to be provided for specific types. -
diff --git a/src/reference/docbook/web-integration.xml b/src/reference/docbook/web-integration.xml index 2fdacade5e..1a198dfdb1 100644 --- a/src/reference/docbook/web-integration.xml +++ b/src/reference/docbook/web-integration.xml @@ -1,19 +1,23 @@ - + 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"> Integrating with other web frameworks -
+
Introduction This chapter details Spring's integration with third party web - frameworks such as JSF, Struts, WebWork, and Tapestry. + frameworks such as JSF, Struts, WebWork, and Tapestry. @@ -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. - + 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 @@
-
+
Common configuration Before diving into the integration specifics of each supported web @@ -83,8 +87,8 @@ a Spring container (a WebApplicationContext) that contains all of the 'business beans' in one's application. - On to specifics: all that one need do is to declare a ContextLoaderListener + On to specifics: all that one need do is to declare a ContextLoaderListener in the standard Java EE servlet web.xml file of one's web application, and add a contextConfigLocation <context-param/> section (in the same file) that defines which set @@ -106,29 +110,29 @@ If you don't specify the contextConfigLocation context parameter, the ContextLoaderListener will look for a file called /WEB-INF/applicationContext.xml - to load. Once the context files are loaded, Spring creates a WebApplicationContext + to load. Once the context files are loaded, Spring creates a WebApplicationContext object based on the bean definitions and stores it in the - ServletContext of the web application. + ServletContext of the web application. 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' ApplicationContext created by the + context' ApplicationContext created by the ContextLoaderListener. WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext); - The WebApplicationContextUtils + The WebApplicationContextUtils class is for convenience, so you don't have to remember the name of the - ServletContext attribute. Its + ServletContext attribute. Its getWebApplicationContext() method will return null if an object doesn't exist under the WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE key. Rather than risk getting NullPointerExceptions in your application, it's better to use the getRequiredWebApplicationContext() method. This method - throws an exception when the ApplicationContext is + throws an exception when the ApplicationContext is missing. Once you have a reference to the @@ -143,7 +147,7 @@ specific integration strategies.
-
+
JavaServer Faces 1.1 and 1.2 JavaServer Faces (JSF) is the JCP's standard component-based, @@ -151,10 +155,10 @@ official part of the Java EE umbrella. For a popular JSF runtime as well as for popular JSF component - libraries, check out the Apache - MyFaces project. The MyFaces project also provides common JSF - extensions such as MyFaces Orchestra: a + libraries, check out the Apache + MyFaces project. The MyFaces project also provides common JSF + extensions such as MyFaces Orchestra: a Spring-based JSF extension that provides rich conversation scope support. @@ -162,9 +166,9 @@ 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 Spring Web Flow - website for details! + within a Spring MVC dispatcher). Check out the Spring Web Flow + website for details! The key element in Spring's JSF integration is the JSF 1.1 @@ -172,13 +176,13 @@ supports the ELResolver mechanism as a next-generation version of JSF EL integration. -
+
DelegatingVariableResolver (JSF 1.1/1.2) The easiest way to integrate one's Spring middle-tier with one's - JSF web layer is to use the - DelegatingVariableResolver class. To + JSF web layer is to use the + DelegatingVariableResolver class. To configure this variable resolver in one's application, one will need to edit one's faces-context.xml file. After the opening <faces-config/> element, add an @@ -221,7 +225,7 @@ </managed-bean>
-
+
SpringBeanVariableResolver (JSF 1.1/1.2) SpringBeanVariableResolver is a variant of @@ -245,7 +249,7 @@ </faces-config>
-
+
SpringBeanFacesELResolver (JSF 1.2+) SpringBeanFacesELResolver is a JSF 1.2 @@ -268,31 +272,31 @@ </faces-config>
-
+
FacesContextUtils A custom VariableResolver works well when mapping one's properties to beans in faces-config.xml, but at times one may need to grab - a bean explicitly. The - FacesContextUtils class makes this easy. + a bean explicitly. The + FacesContextUtils class makes this easy. It is similar to WebApplicationContextUtils, except that it takes a FacesContext parameter - rather than a ServletContext parameter. + rather than a ServletContext parameter. ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
-
+
Apache Struts 1.x and 2.x - Struts used to be the + Struts used to be the de facto web framework for Java applications, mainly - because it was one of the first to be released (June 2001). It has now been renamed to Struts 1 - (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 Struts 1 + (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 @@ Struts 2 is effectively a different product - a successor of WebWork 2.2 (as discussed in ), carrying the - Struts brand now. Check out the Struts 2 Spring - Plugin for the built-in Spring integration shipped with Struts + Struts brand now. Check out the Struts 2 Spring + Plugin 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. @@ -330,11 +334,11 @@ -
+
ContextLoaderPlugin - The ContextLoaderPlugin + The ContextLoaderPlugin is a Struts 1.1+ plug-in that loads a Spring context file for the Struts ActionServlet. This context refers to the root WebApplicationContext (loaded by the @@ -363,9 +367,9 @@ which can be useful when using testing tools like StrutsTestCase. StrutsTestCase's MockStrutsTestCase won't initialize Listeners on startup so putting all your context files in the - plugin is a workaround. (A - bug has been filed for this issue, but has been closed as 'Wont + plugin is a workaround. (A + bug has been filed for this issue, but has been closed as 'Wont Fix'). After configuring this plug-in in @@ -401,12 +405,12 @@ <bean name="/users" .../> -
+
DelegatingRequestProcessor - To configure the - DelegatingRequestProcessor in your + To configure the + DelegatingRequestProcessor in your struts-config.xml file, override the "processorClass" property in the <controller> element. These lines follow the <action-mapping> element. @@ -432,21 +436,21 @@ If you are using Tiles in your Struts application, you must - configure your <controller> with the DelegatingTilesRequestProcessor + configure your <controller> with the DelegatingTilesRequestProcessor instead.
-
+
DelegatingActionProxy If you have a custom RequestProcessor and can't use the DelegatingRequestProcessor or DelegatingTilesRequestProcessor approaches, you - can use the - DelegatingActionProxy as the type in + can use the + DelegatingActionProxy as the type in your action-mapping. <action path="/user" type="org.springframework.web.struts.DelegatingActionProxy" @@ -473,18 +477,18 @@
-
+
ActionSupport Classes As previously mentioned, you can retrieve the WebApplicationContext from the - ServletContext using the + ServletContext using the WebApplicationContextUtils class. An easier way is to extend Spring's Action classes for Struts. For example, instead of subclassing Struts' - Action class, you can subclass Spring's - ActionSupport class. + Action class, you can subclass Spring's + ActionSupport class. The ActionSupport class provides additional convenience methods, like @@ -511,24 +515,24 @@ - the Spring versions merely have Support appended to the name: - ActionSupport, + ActionSupport, - DispatchActionSupport, + DispatchActionSupport, - LookupDispatchActionSupport + LookupDispatchActionSupport and - MappingDispatchActionSupport. + MappingDispatchActionSupport. @@ -541,12 +545,12 @@
-
+
WebWork 2.x - From the WebWork - homepage: - + From the WebWork + homepage: + 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. - One of the key enablers in WebWork's technology stack is an - IoC container to manage Webwork Actions, handle the "wiring" of + One of the key enablers in WebWork's technology stack is an + IoC container 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 @@ 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 Spring-WebWork - integration page on the WebWork wiki + writeup. Please consult the Spring-WebWork + integration page on the WebWork wiki for the full lowdown. 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 - Spring - support forums, too. + Spring + support forums, too.
-
+
Tapestry 3.x and 4.x - From the Tapestry - homepage: - + From the Tapestry + homepage: + 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 [] brackets.) - + 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 Howard M. - Lewis Ship, so hats off to him for what is really some silky + Tapestry creator Howard M. + Lewis Ship, so hats off to him for what is really some silky smooth integration). -
+
Injecting Spring-managed beans 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 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> - + <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> 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 WebApplicationContextUtils.getApplicationContext(servletContext), where servletContext is the standard - ServletContext from the Java EE Servlet + ServletContext from the Java EE Servlet specification. As such, one simple mechanism for a page to get an instance of the UserService, for example, would be with code such as: @@ -757,16 +761,16 @@ UserService userService = (UserService) appContext.getBean("userService"); linkend="tapestry-4-style-di" />. -
+
Dependency Injecting Spring Beans into Tapestry pages First we need to make the - ApplicationContext available to the Tapestry + ApplicationContext available to the Tapestry page or Component without having to have the - ServletContext; this is because at the stage in + ServletContext; this is because at the stage in the page's/component's lifecycle when we need to access the - ApplicationContext, the - ServletContext won't be easily available to the + ApplicationContext, the + ServletContext won't be easily available to the page, so we can't use WebApplicationContextUtils.getApplicationContext(servletContext) 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 { file: xportal.application: <?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>
-
+
Component definition files 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: <?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>
-
+
Adding abstract accessors Now in the Java class definition for the page or component @@ -897,7 +901,7 @@ public abstract AuthenticationService getAuthenticationService(); 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();
-
+
Dependency Injecting Spring Beans into Tapestry pages - Tapestry 4.x style Effecting the dependency injection of Spring-managed beans into Tapestry pages in Tapestry version 4.x is so much - simpler. All that is needed is a single add-on - library, and some (small) amount of (essentially boilerplate) + simpler. All that is needed is a single add-on + library, 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 WEB-INF/lib). @@ -1037,10 +1041,10 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende 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
-
+
Further Resources Find below links to further resources about the various web @@ -1107,24 +1111,24 @@ public abstract class Login extends BasePage implements ErrorProperty, PageRende - The JSF + The JSF homepage - The Struts + The Struts homepage - The WebWork + The WebWork homepage - The Tapestry + The Tapestry homepage diff --git a/src/reference/docbook/xml-custom.xml b/src/reference/docbook/xml-custom.xml index 2c52c8d3e2..45fb238cf8 100644 --- a/src/reference/docbook/xml-custom.xml +++ b/src/reference/docbook/xml-custom.xml @@ -1,24 +1,28 @@ - + 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"> Extensible XML authoring -
+
Introduction 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. - 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 - . - Creating new XML configuration extensions can be done by following these (relatively) - simple steps: - - + 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 + . + Creating new XML configuration extensions can be done by following these (relatively) + simple steps: + + Authoring an XML schema to describe your custom element(s). @@ -33,14 +37,14 @@ Registering the above artifacts with Spring (this too is an easy step). - - - 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 - SimpleDateFormat (from the java.text package) - in an easy manner. When we are done, we will be able to define bean definitions of type - SimpleDateFormat like this: - + + 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 + SimpleDateFormat (from the java.text package) + in an easy manner. When we are done, we will be able to define bean definitions of type + SimpleDateFormat like this: + ]]> @@ -48,13 +52,13 @@ detailed examples follow afterwards. The intent in this first simple example is to walk you through the basic steps involved.)
-
- Authoring the schema - 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 SimpleDateFormat - objects. - <!-- myns.xsd (inside package org/springframework/samples/xml) --> + Authoring the schema + 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 SimpleDateFormat + objects. + <!-- myns.xsd (inside package org/springframework/samples/xml) --> ]]> (The emphasized line contains an extension base for all tags that - will be identifiable (meaning they have an id 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 'beans' - namespace.) - The above schema will be used to configure SimpleDateFormat - objects, directly in an XML application context file using the - <myns:dateformat/> element. - id 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 'beans' + namespace.) + The above schema will be used to configure SimpleDateFormat + objects, directly in an XML application context file using the + <myns:dateformat/> element. + ]]> - 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 - 'dateFormat' of type SimpleDateFormat, with a - couple of properties set. - + 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 + 'dateFormat' of type SimpleDateFormat, with a + couple of properties set. + ]]> - - 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. - -
-
- Coding a <interfacename>NamespaceHandler</interfacename> - In addition to the schema, we need a NamespaceHandler - that will parse all elements of this specific namespace Spring encounters - while parsing configuration files. The NamespaceHandler - should in our case take care of the parsing of the myns:dateformat - element. - The NamespaceHandler interface is pretty simple in that - it features just three methods: - - - init() - allows for initialization of - the NamespaceHandler and will be called by Spring - before the handler is used - - - BeanDefinition parse(Element, ParserContext) - - 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. - - - BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext) - - 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 - out-of-the-box scopes Spring 2.0 supports. - We'll start by highlighting a simple example, without using decoration, after which - we will show decoration in a somewhat more advanced example. - - - Although it is perfectly possible to code your own - NamespaceHandler 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 <myns:dateformat/> element - results in a single SimpleDateFormat bean definition). - Spring features a number of convenience classes that support this scenario. - In this example, we'll make use the NamespaceHandlerSupport class: - + 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. + +
+
+ Coding a <interfacename>NamespaceHandler</interfacename> + In addition to the schema, we need a NamespaceHandler + that will parse all elements of this specific namespace Spring encounters + while parsing configuration files. The NamespaceHandler + should in our case take care of the parsing of the myns:dateformat + element. + The NamespaceHandler interface is pretty simple in that + it features just three methods: + + + init() - allows for initialization of + the NamespaceHandler and will be called by Spring + before the handler is used + + + BeanDefinition parse(Element, ParserContext) - + 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. + + + BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext) - + 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 + out-of-the-box scopes Spring 2.0 supports. + We'll start by highlighting a simple example, without using decoration, after which + we will show decoration in a somewhat more advanced example. + + + Although it is perfectly possible to code your own + NamespaceHandler 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 <myns:dateformat/> element + results in a single SimpleDateFormat bean definition). + Spring features a number of convenience classes that support this scenario. + In this example, we'll make use the NamespaceHandlerSupport class: + } } 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 BeanDefinitionParsers to do the grunt work of the XML parsing; this means that each BeanDefinitionParser will contain just the logic for parsing a single custom element, as we can see in the next step -
-
- Coding a <interfacename>BeanDefinitionParser</interfacename> - A BeanDefinitionParser will be used if the - NamespaceHandler encounters an XML element of the type - that has been mapped to the specific bean definition parser (which is 'dateformat' - in this case). In other words, the BeanDefinitionParser is - responsible for parsing one 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: - +
+ Coding a <interfacename>BeanDefinitionParser</interfacename> + A BeanDefinitionParser will be used if the + NamespaceHandler encounters an XML element of the type + that has been mapped to the specific bean definition parser (which is 'dateformat' + in this case). In other words, the BeanDefinitionParser is + responsible for parsing one 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: + - - - We use the Spring-provided AbstractSingleBeanDefinitionParser - to handle a lot of the basic grunt work of creating a single - BeanDefinition. - - - We supply the AbstractSingleBeanDefinitionParser superclass - with the type that our single BeanDefinition will represent. - - - In this simple case, this is all that we need to do. The creation of our single - BeanDefinition is handled by the AbstractSingleBeanDefinitionParser - superclass, as is the extraction and setting of the bean definition's unique identifier. -
-
- Registering the handler and the schema - 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 - namespaceHandler and custom XSD file in two special purpose - properties files. These properties files are both placed in a - 'META-INF' 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. -
- <filename>'META-INF/spring.handlers'</filename> - The properties file called 'spring.handlers' contains a mapping - of XML Schema URIs to namespace handler classes. So for our example, we need to write the - following: - - (The ':' character is a valid delimiter in the Java properties format, - and so the ':' character in the URI needs to be escaped with a backslash.) - The first part (the key) of the key-value pair is the URI associated with your custom namespace - extension, and needs to match exactly the value of the - 'targetNamespace' attribute as specified in your custom XSD schema. -
-
- <filename>'META-INF/spring.schemas'</filename> - The properties file called 'spring.schemas' 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 'xsi:schemaLocation' attribute) - to classpath resources. This file is needed to prevent Spring from - absolutely having to use a default EntityResolver 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 'myns.xsd' - in the 'org.springframework.samples.xml' package): - - The upshot of this is that you are encouraged to deploy your XSD file(s) right alongside - the NamespaceHandler and BeanDefinitionParser - classes on the classpath. -
-
-
- Using a custom extension in your Spring XML configuration - 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 <dateformat/> element developed in the - previous steps in a Spring XML configuration file. - + + + We use the Spring-provided AbstractSingleBeanDefinitionParser + to handle a lot of the basic grunt work of creating a single + BeanDefinition. + + + We supply the AbstractSingleBeanDefinitionParser superclass + with the type that our single BeanDefinition will represent. + + + In this simple case, this is all that we need to do. The creation of our single + BeanDefinition is handled by the AbstractSingleBeanDefinitionParser + superclass, as is the extraction and setting of the bean definition's unique identifier. +
+
+ Registering the handler and the schema + 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 + namespaceHandler and custom XSD file in two special purpose + properties files. These properties files are both placed in a + 'META-INF' 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. +
+ <filename>'META-INF/spring.handlers'</filename> + The properties file called 'spring.handlers' contains a mapping + of XML Schema URIs to namespace handler classes. So for our example, we need to write the + following: + + (The ':' character is a valid delimiter in the Java properties format, + and so the ':' character in the URI needs to be escaped with a backslash.) + The first part (the key) of the key-value pair is the URI associated with your custom namespace + extension, and needs to match exactly the value of the + 'targetNamespace' attribute as specified in your custom XSD schema. +
+
+ <filename>'META-INF/spring.schemas'</filename> + The properties file called 'spring.schemas' 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 'xsi:schemaLocation' attribute) + to classpath resources. This file is needed to prevent Spring from + absolutely having to use a default EntityResolver 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 'myns.xsd' + in the 'org.springframework.samples.xml' package): + + The upshot of this is that you are encouraged to deploy your XSD file(s) right alongside + the NamespaceHandler and BeanDefinitionParser + classes on the classpath. +
+
+
+ Using a custom extension in your Spring XML configuration + 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 <dateformat/> element developed in the + previous steps in a Spring XML configuration file. + ]]> -
-
- Meatier examples - Find below some much meatier examples of custom XML extensions. -
- Nesting custom tags within custom tags - This example illustrates how you might go about writing the various artifacts - required to satisfy a target of the following configuration: - +
+
+ Meatier examples + Find below some much meatier examples of custom XML extensions. +
+ Nesting custom tags within custom tags + This example illustrates how you might go about writing the various artifacts + required to satisfy a target of the following configuration: + components = new ArrayList (); - ]]>// mmm, there is no setter method for the 'components'// mmm, there is no setter method for the 'components' 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 childElements, BeanDefinitionBuilder factory) { ManagedList children = new ManagedList(childElements.size()); - + for (Element element : childElements) { children.add(parseComponentElement(element)); } - + factory.addPropertyValue("children", children); } }]]> Lastly, the various artifacts need to be registered with the Spring XML infrastructure. - # in 'META-INF/spring.handlers'# in 'META-INF/spring.handlers' - # in 'META-INF/spring.schemas'# in 'META-INF/spring.schemas' -
-
- Custom attributes on 'normal' elements - 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. - 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 - JCache, and you want to ensure that - the named JCache instance is eagerly started within the surrounding cluster: - jcache:cache-name="checking.account"> +
+ Custom attributes on 'normal' elements + 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. + 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 + JCache, and you want to ensure that + the named JCache instance is eagerly started within the surrounding cluster: + jcache:cache-name="checking.account"><!-- other dependencies here... -->]]> What we are going to do here is create another BeanDefinition @@ -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 } ]]> Lastly, the various artifacts need to be registered with the Spring XML infrastructure. - # in 'META-INF/spring.handlers'# in 'META-INF/spring.handlers' - # in 'META-INF/spring.schemas'# in 'META-INF/spring.schemas' -
-
-
- Further Resources - Find below links to further resources concerning XML Schema and the extensible XML support - described in this chapter. - - - The XML Schema Part 1: Structures Second Edition - - - The XML Schema Part 2: Datatypes Second Edition - - -
+
+
+
+ Further Resources + Find below links to further resources concerning XML Schema and the extensible XML support + described in this chapter. + + + The XML Schema Part 1: Structures Second Edition + + + The XML Schema Part 2: Datatypes Second Edition + + +
diff --git a/src/reference/docbook/xsd-configuration.xml b/src/reference/docbook/xsd-configuration.xml index 99cab4926a..c7f3eb26fc 100644 --- a/src/reference/docbook/xsd-configuration.xml +++ b/src/reference/docbook/xsd-configuration.xml @@ -1,10 +1,14 @@ - + 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"> XML Schema-based configuration -
+
Introduction This appendix details the XML Schema-based configuration introduced in Spring 2.0 and enhanced and extended in Spring 2.5 and 3.0. @@ -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 .
-
+
XML Schema-based configuration -
+
Referencing the schemas To switch over from the DTD-style to the new XML Schema-style, you need to make the following change. @@ -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 demonstrates how you can start immediately by using some of the more common utility tags. + 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 before snippet of XML showing + the old (but still 100% legal and supported) style, followed immediately + by an after example showing the equivalent in the new XML Schema-based + style.
- 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 before snippet of XML showing - the old (but still 100% legal and supported) style, followed immediately - by an after example showing the equivalent in the new XML Schema-based - style. -
+
The <literal>util</literal> schema First up is coverage of the util tags. As the name implies, the util tags deal with common, utility @@ -112,7 +116,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]><!-- bean definitions here -->]]> -
+
<literal><util:constant/></literal> Before... @@ -137,10 +141,10 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]> -
+
Setting a bean property or constructor arg from a field value - FieldRetrievingFactoryBean + FieldRetrievingFactoryBean is a FactoryBean which retrieves a static or non-static field value. It is typically used for retrieving public static @@ -149,7 +153,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem Find below an example which shows how a static field is exposed, by - using the staticField + using the staticField property: It is also possible to access a non-static (instance) field of another bean, as described in the API documentation for the - FieldRetrievingFactoryBean + FieldRetrievingFactoryBean class. @@ -216,7 +220,7 @@ public class Client {
-
+
<literal><util:property-path/></literal> Before... <!-- target bean to be referenced by name -->]]> The value of the 'path' attribute of the <property-path/> tag follows the form 'beanName.beanProperty'. -
+
Using <literal><util:property-path/></literal> to set a bean property or constructor-argument PropertyPathFactoryBean is a FactoryBean 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.
-
+
<literal><util:properties/></literal> Before... - <!-- creates a java.util.Properties instance with values loaded from the supplied location --><!-- creates a java.util.Properties instance with values loaded from the supplied location --> ]]> @@ -319,13 +323,13 @@ public class Client { the supplied Resource location). After... - <!-- creates a java.util.Properties instance with values loaded from the supplied location --><!-- creates a java.util.Properties instance with values loaded from the supplied location -->]]>
-
+
<literal><util:list/></literal> Before... - <!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' --><!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' --> @@ -342,7 +346,7 @@ public class Client { with values taken from the supplied 'sourceList'. After... - <!-- creates a java.util.List instance with the supplied values --><!-- creates a java.util.List instance with the supplied values --> pechorin@hero.org raskolnikov@slums.org @@ -369,10 +373,10 @@ public class Client { . -->
-
+
<literal><util:map/></literal> Before... - <!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' --><!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' --> @@ -389,7 +393,7 @@ public class Client { with key-value pairs taken from the supplied 'sourceMap'. After... - <!-- creates a java.util.Map instance with the supplied key-value pairs --><!-- creates a java.util.Map instance with the supplied key-value pairs --> @@ -416,10 +420,10 @@ public class Client { . -->
-
+
<literal><util:set/></literal> Before... - <!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' --><!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' --> @@ -436,7 +440,7 @@ public class Client { with values taken from the supplied 'sourceSet'. After... - <!-- creates a java.util.Set instance with the supplied values --><!-- creates a java.util.Set instance with the supplied values --> pechorin@hero.org raskolnikov@slums.org @@ -464,7 +468,7 @@ public class Client { -->
-
+
The <literal>jee</literal> schema The jee tags deal with Java EE (Java Enterprise Edition)-related configuration issues, such as looking up a JNDI object and defining EJB references. @@ -483,7 +487,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]><!-- bean definitions here -->]]> -
+
<literal><jee:jndi-lookup/></literal> (simple) Before... @@ -502,7 +506,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem dataSource"/>]]>
-
+
<literal><jee:jndi-lookup/></literal> (with single JNDI environment setting) Before... @@ -518,7 +522,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem foo=bar ]]>
-
+
<literal><jee:jndi-lookup/></literal> (with multiple JNDI environment settings) Before... @@ -532,14 +536,14 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]> After... - ]]><!-- newline-separated, key-value pairs for the environment (standard Properties format) --><!-- newline-separated, key-value pairs for the environment (standard Properties format) --> foo=bar ping=pong ]]>
-
+
<literal><jee:jndi-lookup/></literal> (complex) Before... @@ -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"/>]]>
-
+
<literal><jee:local-slsb/></literal> (simple) The <jee:local-slsb/> tag configures a reference to an EJB Stateless SessionBean. @@ -573,7 +577,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]>
-
+
<literal><jee:local-slsb/></literal> (complex) @@ -591,7 +595,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem lookup-home-on-startup="true" resource-ref="true">]]>
-
+
<literal><jee:remote-slsb/></literal> The <jee:remote-slsb/> tag configures a reference to a remote EJB Stateless SessionBean. @@ -617,7 +621,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem refresh-home-on-connect-failure="true">]]>
-
+
The <literal>lang</literal> schema The lang 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 ]]>
-
+
The <literal>jms</literal> schema The jms tags deal with configuring JMS-related beans such as Spring's MessageListenerContainers. @@ -668,7 +672,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]>
-
+
The <literal>tx</literal> (transaction) schema The tx 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 aop namespace are available to you.
-
+
The <literal>aop</literal> schema The aop 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 ]]>
-
+
The <literal>context</literal> schema The context tags deal with ApplicationContext 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 The context schema was only introduced in Spring 2.5. -
+
<literal><property-placeholder/></literal> This element activates the replacement of ${...} placeholders, resolved against the specified properties file (as a Spring resource location). @@ -762,7 +766,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem for you; if you need more control over the PropertyPlaceholderConfigurer, just define one yourself explicitly.
-
+
<literal><annotation-config/></literal> Activates the Spring infrastructure for various annotations to be detected in bean classes: Spring's @Required @@ -780,25 +784,25 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem for that purpose.
-
+
<literal><component-scan/></literal> This element is detailed in .
-
+
<literal><load-time-weaver/></literal> This element is detailed in .
-
+
<literal><spring-configured/></literal> This element is detailed in .
-
+
<literal><mbean-export/></literal> This element is detailed in .
-
+
The <literal>tool</literal> schema The tool 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.
-
+
The <literal>jdbc</literal> schema The jdbc 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 ]]>
-
+
The <literal>cache</literal> schema The cache tags can be used to enable support for Spring's @CacheEvict, @CachePut @@ -862,7 +866,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schem ]]>
-
+
The <literal>beans</literal> schema Last but not least we have the tags in the beans 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