diff --git a/spring-framework-reference/src/scheduling.xml b/spring-framework-reference/src/scheduling.xml
index 30485aa7ed9..c25d60d68c9 100644
--- a/spring-framework-reference/src/scheduling.xml
+++ b/spring-framework-reference/src/scheduling.xml
@@ -383,6 +383,139 @@ public class TaskExecutorExample {
as scheduled, and potentially recurring, executions.
+
+
+ The Task Namespace
+
+ Beginning with Spring 3.0, there is an XML namespace for configuring
+ TaskExecutor and
+ 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
+ ThreadPoolTaskScheduler instance with the
+ specified thread pool size.
+ ]]>
+
+ The value provided for the "id" attribute will be used as the
+ prefix for thread names within the pool. The 'scheduler' element is
+ relatively straightforward. If you do not provide a 'size' attribute,
+ the default thread pool will only have a single thread. There are no
+ other configuration options for the scheduler.
+
+
+
+ The 'executor' element
+ The following will create a
+ ThreadPoolTaskExecutor instance:
+ ]]>
+
+
+ As with the scheduler above, the value provided for the "id"
+ attribute will be used as the prefix for thread names within the pool.
+ As far as the pool size is concerned, the 'executor' element supports
+ more configuration options than the 'scheduler' element. For one thing,
+ the thread pool for a ThreadPoolTaskExecutor is
+ itself more configurable. Rather than just a single size, an executor's
+ thread pool may have different values for the core
+ and the max size. If a single value is provided
+ then the executor will have a fixed-size thread pool (the core and max
+ sizes are the same). However, the 'executor' element's 'size' attribute
+ also accepts a range in the form of "m-n".
+ ]]>
+
+
+ As you can see from that configuration, a 'queue-capacity' value
+ 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.
+ 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
+ task will be added to the queue as long as its capacity has not yet
+ been reached. Only then, if the queue's capacity
+ has been reached, will the executor create a new
+ thread beyond the core size. If the max size has also been reached,
+ then the executor will reject the task.
+
+ By default, the queue is unbounded, but this
+ is rarely the desired configuration, because it can lead to
+ OutOfMemoryErrors if enough tasks are added to
+ that queue while all pool threads are busy. Furthermore, if the queue
+ is unbounded, then the max size has no effect at all. Since the
+ executor will always try the queue before creating a new thread beyond
+ the core size, a queue must have a finite capacity for the thread pool
+ to grow beyond the core size (this is why a "fixed-size" pool is the
+ only sensible case when using an unbounded queue).
+
+ In a moment, we will review the effects of the keep-alive setting
+ which adds yet another factor to consider when providing a pool size
+ configuration. First, let's consider the case, as mentioned above, when
+ a task is rejected. By default, when a task is rejected, a thread pool
+ executor will throw a TaskRejectedException.
+ However, the rejection policy is actually configurable. The exception
+ is thrown when using the default rejection policy which is the
+ AbortPolicy implementation. For applications
+ where some tasks can be skipped under heavy load, either the
+ DiscardPolicy or
+ DiscardOldestPolicy may be configured instead.
+ Another option that works well for applications that need to throttle
+ the submitted tasks under heavy load is the
+ CallerRunsPolicy. Instead of throwing an
+ exception or discarding tasks, that policy will simply force the thread
+ that is calling the submit method to run the task itself. The idea is
+ that such a caller will be busy while running that task and not able to
+ submit other tasks immediately. Therefore it provides a simple way to
+ throttle the incoming load while maintaining the limits of the thread
+ pool and queue. Typically this allows the executor to "catch up" on the
+ tasks it is handling and thereby frees up some capacity on the queue,
+ in the pool, or both. Any of these options can be chosen from an
+ enumeration of values available for the 'rejection-policy' attribute on
+ the 'executor' element.
+ ]]>
+
+
+
+ The 'scheduled-tasks' element
+
+ The most powerful feature of Spring's task namespace is the
+ support for configuring tasks to be scheduled within a Spring
+ Application Context. This follows an approach similar to other
+ "method-invokers" in Spring, such as that provided by the JMS namespace
+ for configuring Message-driven POJOs. Basically a "ref" attribute can
+ point to any Spring-managed object, and the "method" attribute provides
+ the name of a method to be invoked on that object. Here is a simple
+ example.
+
+
+
+
+ ]]>
+
+ As you can see, the scheduler is referenced by the outer element,
+ and each individual task includes the configuration of its trigger
+ metadata. In the preceding example, that metadata defines a periodic
+ trigger with a fixed delay. It could also be configured with a
+ "fixed-rate", or for more control, a "cron" attribute could be provided
+ instead. Here's an example featuring these other options.
+
+
+
+
+
+ ]]>
+
+
+
Using the OpenSymphony Quartz Scheduler
Quartz uses Trigger, Job and