231 lines
10 KiB
XML
231 lines
10 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
/*
|
|
* Copyright 2002-2008 the original author or authors.
|
|
*
|
|
* Licensed 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.
|
|
*/
|
|
-->
|
|
<chapter version="5" xml:id="scheduling" xmlns="http://docbook.org/ns/docbook"
|
|
xmlns:ns5="http://www.w3.org/1999/xhtml"
|
|
xmlns:ns42="http://www.w3.org/2000/svg"
|
|
xmlns:ns4="http://www.w3.org/1999/xlink"
|
|
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
|
|
xmlns:ns="http://docbook.org/ns/docbook">
|
|
<title>Scheduling and Thread Pooling</title>
|
|
|
|
<section xml: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/" />). The scheduler is set up using
|
|
a <literal>IFactoryObject</literal> with optional references to
|
|
<literal>Trigger</literal> instances, respectively. Furthermore, a
|
|
convenience class for the Quartz Scheduler is available that allows you to
|
|
invoke a method of an existing target object.</para>
|
|
</section>
|
|
|
|
<section xml:id="scheduling-quartz">
|
|
<title>Using the Quartz.NET Scheduler</title>
|
|
|
|
<para>Quartz uses <literal>Trigger</literal>, <literal>Job</literal> and
|
|
<literal>JobDetail</literal> 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/" />. For convenience purposes,
|
|
Spring offers a couple of classes that simplify the usage of Quartz within
|
|
Spring-based applications.</para>
|
|
|
|
<section xml:id="scheduling-quartz-jobdetail">
|
|
<title>Using the JobDetailObject</title>
|
|
|
|
<para><literal>JobDetail</literal> objects contain all information
|
|
needed to run a job. The Spring Framework provides a
|
|
<literal>JobDetailObject</literal> that makes the
|
|
<literal>JobDetail</literal> easier to configure and with sensible
|
|
defaults. Let's have a look at an example:</para>
|
|
|
|
<programlisting language="myxml">
|
|
<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
|
|
(<literal>ExampleJob</literal>). The timeout is specified in the job
|
|
data dictionary. The job data dictonary is available through the
|
|
<literal>JobExecutionContext</literal> (passed to you at execution
|
|
time), but the <literal>JobDetailObject</literal> also maps the
|
|
properties from the job data map to properties of the actual job. So in
|
|
this case, if the <literal>ExampleJob</literal> contains a property
|
|
named <literal>Timeout</literal>, the <literal>JobDetailObject</literal>
|
|
will automatically apply it:</para>
|
|
|
|
<programlisting language="csharp">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 xml:id="scheduling-quartz-method-invoking-job">
|
|
<title>Using the
|
|
<literal>MethodInvokingJobDetailFactoryObject</literal></title>
|
|
|
|
<para>Often you just need to invoke a method on a specific object. Using
|
|
the <literal>MethodInvokingJobDetailFactoryObject</literal> you can do
|
|
exactly this:</para>
|
|
|
|
<programlisting language="myxml"><object id="JobDetail" type="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 language="csharp">public class ExampleBusinessObject {
|
|
|
|
<lineannotation>// properties and collaborators</lineannotation>
|
|
|
|
public void DoIt() {
|
|
<lineannotation>// do the actual work</lineannotation>
|
|
}
|
|
}</programlisting>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="ExampleBusinessObject" type="Examples.BusinessObjects.ExampleBusinessObject, Examples.BusinessObjects"/></programlisting>
|
|
|
|
<para>Using the <literal>MethodInvokingJobDetailFactoryObject</literal>,
|
|
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 <literal>JobDetail</literal>, it might be possible
|
|
that before the first job has finished, the second one will start. If
|
|
<literal>JobDetail</literal> classes implement the
|
|
<literal>Stateful</literal> interface, this won't happen. The second job
|
|
will not start before the first one has finished. To make jobs resulting
|
|
from the <literal>MethodInvokingJobDetailFactoryObject</literal>
|
|
non-concurrent, set the <literal>concurrent</literal> flag to
|
|
<literal>false</literal>.</para>
|
|
|
|
<programlisting language="myxml"><object id="JobDetail" type="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>
|
|
|
|
<para>Also note that when using MethodInvokingJobDetailFactoryObject
|
|
you can't use database persistence for Jobs. See the class
|
|
documentation for additional details.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section xml:id="scheduling-quartz-cron">
|
|
<title>Wiring up jobs using triggers and the
|
|
<literal>SchedulerFactoryObject</literal></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 <literal>SchedulerFactoryObject</literal>.
|
|
Several triggers are available within Quartz. Spring offers two
|
|
subclassed triggers with convenient defaults:
|
|
<literal>CronTriggerObject</literal> and
|
|
<literal>SimpleTriggerObject</literal></para>
|
|
|
|
<para>Triggers need to be scheduled. Spring offers a
|
|
<literal>SchedulerFactoryObject</literal> that exposes triggers to be
|
|
set as properties. <literal>SchedulerFactoryObject</literal> schedules
|
|
the actual jobs with those triggers.</para>
|
|
|
|
<para>Find below a couple of examples:</para>
|
|
|
|
<programlisting language="myxml"><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="CronExpressionString" 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
|
|
<literal>SchedulerFactoryObject</literal>:</para>
|
|
|
|
<programlisting language="myxml"><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
|
|
<literal>SchedulerFactoryObjecct</literal> 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>
|