changes for 1.2 M1 release packaging.
This commit is contained in:
209
doc/reference/src/scheduling.xml
Normal file
209
doc/reference/src/scheduling.xml
Normal file
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="scheduling">
|
||||
<title>Scheduling and Thread Pooling</title>
|
||||
|
||||
<section id="scheduling-introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>The Spring Framework features integration classes for scheduling
|
||||
support. Currently, Spring supports the Quartz Scheduler (<ulink
|
||||
url="http://quartznet.sourceforge.net/"></ulink>). The scheduler is set up
|
||||
using a <interfacename>IFactoryObject</interfacename> with optional
|
||||
references to <classname>Trigger</classname> instances, respectively.
|
||||
Furthermore, a convenience class for both the Quartz Scheduler is
|
||||
available that allows you to invoke a method of an existing target
|
||||
object.</para>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-quartz">
|
||||
<title>Using the Quartz.NET Scheduler</title>
|
||||
|
||||
<para>Quartz uses <classname>Trigger</classname>,
|
||||
<classname>Job</classname> and <classname>JobDetail</classname> objects to
|
||||
realize scheduling of all kinds of jobs. For the basic concepts behind
|
||||
Quartz, have a look at <ulink
|
||||
url="http://quartznet.sourceforge.net/"></ulink>. For convenience
|
||||
purposes, Spring offers a couple of classes that simplify the usage of
|
||||
Quartz within Spring-based applications.</para>
|
||||
|
||||
<section id="scheduling-quartz-jobdetail">
|
||||
<title>Using the JobDetailObject</title>
|
||||
|
||||
<para><classname>JobDetail</classname> objects contain all information
|
||||
needed to run a job. The Spring Framework provides a
|
||||
<classname>JobDetailObject</classname> that makes the
|
||||
<classname>JobDetail</classname> easier to configure and with sensible
|
||||
defaults. Let's have a look at an example:</para>
|
||||
|
||||
<programlisting>
|
||||
<object name="ExampleJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
|
||||
<property name="JobType" value="Example.Quartz.ExampleJob, Example.Quartz" />
|
||||
<property name="JobDataAsMap">
|
||||
<dictionary>
|
||||
<entry key="Timeout" value="5" />
|
||||
</dictionary>
|
||||
</property>
|
||||
</object></programlisting>
|
||||
|
||||
<para>The job detail object has all information it needs to run the job
|
||||
(<classname>ExampleJob</classname>). The timeout is specified in the job
|
||||
data dictionary. The job data dictonary is available through the
|
||||
<classname>JobExecutionContext</classname> (passed to you at execution
|
||||
time), but the <classname>JobDetailObject</classname> also maps the
|
||||
properties from the job data map to properties of the actual job. So in
|
||||
this case, if the <classname>ExampleJob</classname> contains a property
|
||||
named <literal>Timeout</literal>, the
|
||||
<classname>JobDetailObject</classname> will automatically apply
|
||||
it:</para>
|
||||
|
||||
<programlisting>namespace Example.Quartz;
|
||||
|
||||
public class ExampleJob extends QuartzJobObject {
|
||||
|
||||
private int timeout;
|
||||
|
||||
/// <summary>
|
||||
/// Setter called after the ExampleJob is instantiated
|
||||
/// with the value from the JobDetailObject (5)
|
||||
/// </summary>
|
||||
public int Timeout {
|
||||
set { timeout = value; };
|
||||
}
|
||||
|
||||
protected override void ExecuteInternal(JobExecutionContext context) {
|
||||
<lineannotation>// do the actual work</lineannotation>
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>All additional settings from the job detail object are of course
|
||||
available to you as well.</para>
|
||||
|
||||
<para><emphasis>Note: Using the <literal>name</literal> and
|
||||
<literal>group</literal> properties, you can modify the name and the
|
||||
group of the job, respectively. By default, the name of the job matches
|
||||
the object name of the job detail object (in the example above, this is
|
||||
<literal>ExampleJob</literal>).</emphasis></para>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-quartz-method-invoking-job">
|
||||
<title>Using the
|
||||
<classname>MethodInvokingJobDetailFactoryObject</classname></title>
|
||||
|
||||
<para>Often you just need to invoke a method on a specific object. Using
|
||||
the <classname>MethodInvokingJobDetailFactoryObject</classname> you can
|
||||
do exactly this:</para>
|
||||
|
||||
<programlisting><object id="JobDetail" class="Spring.Scheduling.Quartz.MethodInvokingJobDetailFactoryObject, Spring.Scheduling.Quartz">
|
||||
<property name="TargetObject" ref="ExampleBusinessObject" />
|
||||
<property name="TargetMethod" value="DoIt" />
|
||||
</object></programlisting>
|
||||
|
||||
<para>The above example will result in the <literal>doIt</literal>
|
||||
method being called on the <literal>exampleBusinessObject</literal>
|
||||
method (see below):</para>
|
||||
|
||||
<programlisting>public class ExampleBusinessObject {
|
||||
|
||||
<lineannotation>// properties and collaborators</lineannotation>
|
||||
|
||||
public void DoIt() {
|
||||
<lineannotation>// do the actual work</lineannotation>
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<programlisting>
|
||||
<object id="ExampleBusinessObject" class="Examples.BusinessObjects.ExampleBusinessObject, Examples.BusinessObjects"/></programlisting>
|
||||
|
||||
<para>Using the
|
||||
<classname>MethodInvokingJobDetailFactoryObject</classname>, you don't
|
||||
need to create one-line jobs that just invoke a method, and you only
|
||||
need to create the actual business object and wire up the detail
|
||||
object.</para>
|
||||
|
||||
<para>By default, Quartz Jobs are stateless, resulting in the
|
||||
possibility of jobs interfering with each other. If you specify two
|
||||
triggers for the same <classname>JobDetail</classname>, it might be
|
||||
possible that before the first job has finished, the second one will
|
||||
start. If <classname>JobDetail</classname> classes implement the
|
||||
<interfacename>Stateful</interfacename> interface, this won't happen.
|
||||
The second job will not start before the first one has finished. To make
|
||||
jobs resulting from the
|
||||
<classname>MethodInvokingJobDetailFactoryObject</classname>
|
||||
non-concurrent, set the <literal>concurrent</literal> flag to
|
||||
<literal>false</literal>.</para>
|
||||
|
||||
<programlisting><object id="JobDetail" class="Spring.Scheduling.Quartz.MethodInvokingJobDetailFactoryObject, Spring.Scheduling.Quartz">
|
||||
<property name="TargetObject" ref="ExampleBusinessObject" />
|
||||
<property name="TargetMethod" value="DoIt" />
|
||||
<property name="Concurrent" value="false" />
|
||||
</object>
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>By default, jobs will run in a concurrent fashion.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-quartz-cron">
|
||||
<title>Wiring up jobs using triggers and the
|
||||
<classname>SchedulerFactoryObject</classname></title>
|
||||
|
||||
<para>We've created job details and jobs. We've also reviewed the
|
||||
convenience class that allows to you invoke a method on a specific
|
||||
object. Of course, we still need to schedule the jobs themselves. This
|
||||
is done using triggers and a
|
||||
<classname>SchedulerFactoryObject</classname>. Several triggers are
|
||||
available within Quartz. Spring offers two subclassed triggers with
|
||||
convenient defaults: <classname>CronTriggerObject</classname> and
|
||||
<classname>SimpleTriggerObject</classname></para>
|
||||
|
||||
<para>Triggers need to be scheduled. Spring offers a
|
||||
<classname>SchedulerFactoryObject</classname> that exposes triggers to
|
||||
be set as properties. <classname>SchedulerFactoryObject</classname>
|
||||
schedules the actual jobs with those triggers.</para>
|
||||
|
||||
<para>Find below a couple of examples:</para>
|
||||
|
||||
<programlisting><object id="SimpleTrigger" type="Spring.Scheduling.Quartz.SimpleTriggerObject, Spring.Scheduling.Quartz">
|
||||
<!-- see the example of method invoking job above -->
|
||||
<property name="JobDetail" ref="ExampleJob" />
|
||||
|
||||
<!-- 10 seconds -->
|
||||
<property name="StartDelay" value="10s" />
|
||||
|
||||
<!-- repeat every 50 seconds -->
|
||||
<property name="RepeatInterval" value="50s" />
|
||||
</object>
|
||||
|
||||
<object id="CronTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz">
|
||||
<property name="JobDetail" ref="ExampleJob" />
|
||||
|
||||
<!-- run every morning at 6 AM -->
|
||||
<property name="CronExpression" value="0 0 6 * * ?" />
|
||||
</object>
|
||||
</programlisting>
|
||||
|
||||
<para>Now we've set up two triggers, one running every 50 seconds with a
|
||||
starting delay of 10 seconds and one every morning at 6 AM. To finalize
|
||||
everything, we need to set up the
|
||||
<classname>SchedulerFactoryObject</classname>:</para>
|
||||
|
||||
<programlisting><object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
|
||||
<property name="triggers">
|
||||
<list>
|
||||
<ref object="CronTrigger" />
|
||||
<ref object="SimpleTrigger" />
|
||||
</list>
|
||||
</property>
|
||||
</object>
|
||||
</programlisting>
|
||||
|
||||
<para>More properties are available for the
|
||||
<classname>SchedulerFactoryObjecct</classname> for you to set, such as
|
||||
the calendars used by the job details, properties to customize Quartz
|
||||
with, etc. Have a look at the <ulink
|
||||
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html">SchedulerFactoryObject
|
||||
SDK docs</ulink> for more information.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user