Added documentation for the TaskScheduler abstraction.
This commit is contained in:
parent
ce3c72f8c2
commit
eb5d47c64e
|
|
@ -267,6 +267,7 @@ public class ExampleJob extends QuartzJobBean {
|
|||
</section>
|
||||
<section id="scheduling-task-executor">
|
||||
<title>The Spring <interfacename>TaskExecutor</interfacename> abstraction</title>
|
||||
|
||||
<para>Spring 2.0 introduces a new abstraction for dealing with
|
||||
executors. Executors are the Java 5 name for the concept of
|
||||
thread pools. The "executor" naming is due to the fact that there
|
||||
|
|
@ -499,4 +500,127 @@ public class TaskExecutorExample {
|
|||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-task-scheduler">
|
||||
<title>The Spring <interfacename>TaskScheduler</interfacename> abstraction</title>
|
||||
|
||||
<para>In addition to the <interfacename>TaskExecutor</interfacename>
|
||||
abstraction, Spring 3.0 introduces a <interfacename>TaskScheduler</interfacename>
|
||||
with a variety of methods for scheduling tasks to run at some point in the future.
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[public interface TaskScheduler {
|
||||
|
||||
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
||||
|
||||
ScheduledFuture schedule(Runnable task, Date startTime);
|
||||
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
|
||||
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
|
||||
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
|
||||
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
||||
|
||||
}]]></programlisting>
|
||||
|
||||
<para>The simplest method is the one named 'schedule' that takes a
|
||||
<interfacename>Runnable</interfacename> and <classname>Date</classname>
|
||||
only. That will cause the task to run once after the specified time. All of
|
||||
the other methods are capable of scheduling tasks to run repeatedly. The
|
||||
fixed-rate and fixed-delay methods are for simple, periodic execution, but
|
||||
the method that accepts a Trigger is much more flexible.</para>
|
||||
|
||||
<section id="scheduling-trigger-interface">
|
||||
<title>The <interfacename>Trigger</interfacename> interface</title>
|
||||
|
||||
<para>The <interfacename>Trigger</interfacename> interface is
|
||||
essentially inspired by JSR-236, which, as of Spring 3.0, has not yet
|
||||
been officially implemented. The basic idea of the
|
||||
<interfacename>Trigger</interfacename> is that execution times may be
|
||||
determined based on past execution outcomes or even arbitrary
|
||||
conditions. If these determinations do take into account the outcome of
|
||||
the preceding execution, that information is available within a
|
||||
<interfacename>TriggerContext</interfacename>. The
|
||||
<interfacename>Trigger</interfacename> interface itself is quite
|
||||
simple:</para>
|
||||
<programlisting language="java"><![CDATA[public interface Trigger {
|
||||
|
||||
Date nextExecutionTime(TriggerContext triggerContext);
|
||||
|
||||
}]]></programlisting>
|
||||
|
||||
<para>As you can see, the <interfacename>TriggerContext</interfacename>
|
||||
is the most important part. It encapsulates all of the relevant data,
|
||||
and is open for extension in the future if necessary. The
|
||||
<interfacename>TriggerContext</interfacename> is an interface (a
|
||||
<classname>SimpleTriggerContext</classname> implementation is used by
|
||||
default). Here you can see what methods are available for
|
||||
<interfacename>Trigger</interfacename> implementations.</para>
|
||||
<programlisting language="java"><![CDATA[public interface TriggerContext {
|
||||
|
||||
Date lastScheduledExecutionTime();
|
||||
|
||||
Date lastActualExecutionTime();
|
||||
|
||||
Date lastCompletionTime();
|
||||
|
||||
}]]></programlisting>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-trigger-implementations">
|
||||
<title><interfacename>Trigger</interfacename> implementations</title>
|
||||
|
||||
<para>Spring provides two implementations of the
|
||||
<interfacename>Trigger</interfacename> interface. The most interesting
|
||||
one is the <classname>CronTrigger</classname>. It enables the
|
||||
scheduling of tasks based on cron expressions. For example the
|
||||
following task is being scheduled to run 15 minutes past each hour but
|
||||
only during the 9-to-5 "business hours" on weekdays.</para>
|
||||
<programlisting language="java"><![CDATA[scheduler.schedule(task, new CronTrigger("* 15 9-17 * * MON-FRI"));]]></programlisting>
|
||||
|
||||
<para>The other out-of-the-box implementation is a
|
||||
<classname>PeriodicTrigger</classname> that accepts a fixed period, an
|
||||
optional initial delay value, and a boolean to indicate whether the
|
||||
period should be interpreted as a fixed-rate or a fixed-delay. Since
|
||||
the <interfacename>TaskScheduler</interfacename> interface already
|
||||
defines methods for scheduling tasks at a fixed-rate or with a
|
||||
fixed-delay, those methods should be used directly whenever possible.
|
||||
The value of the <classname>PeriodicTrigger</classname> implementation
|
||||
is that it can be used within components that rely on the
|
||||
<interfacename>Trigger</interfacename> abstraction. For example, it may
|
||||
be convenient to allow periodic triggers, cron-based triggers, and even
|
||||
custom trigger implementations to be used interchangeably. Such a
|
||||
component could take advantage of dependency injection so that such
|
||||
<interfacename>Triggers</interfacename> could be configured externally.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-task-scheduler-implementations">
|
||||
<title><interfacename>TaskScheduler</interfacename> implementations</title>
|
||||
|
||||
<para>As with Spring's <interfacename>TaskExecutor</interfacename>
|
||||
abstraction, the primary benefit of the
|
||||
<interfacename>TaskScheduler</interfacename> is that code relying on
|
||||
scheduling behavior need not be coupled to a particular scheduler
|
||||
implementation. The flexibility this provides is particularly relevant
|
||||
when running within Application Server environments where threads
|
||||
should not be created directly by the application itself. For such
|
||||
cases, Spring provides a
|
||||
<classname>TimerManagerTaskScheduler</classname> that delegates to a
|
||||
CommonJ TimerManager instance, typically configured with a JNDI-lookup.
|
||||
</para>
|
||||
|
||||
<para>A simpler alternative, the
|
||||
<classname>ThreadPoolTaskScheduler</classname>, can be used whenever
|
||||
external thread management is not a requirement. Internally, it
|
||||
delegates to a <interfacename>ScheduledExecutorService</interfacename>
|
||||
instance. <classname>ThreadPoolTaskScheduler</classname> actually
|
||||
implements Spring's <interfacename>TaskExecutor</interfacename>
|
||||
interface as well, so that a single instance can be used for
|
||||
asynchronous execution <emphasis>as soon as possible</emphasis> as well
|
||||
as scheduled, and potentially recurring, executions.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
Loading…
Reference in New Issue