Chapter 22. Scheduling jobs using Quartz or Timer

22.1. Introduction

Spring features integration classes for scheduling support. Currently, Spring
supports the Timer, part of the JDK since 1.3, and the Quartz Scheduler
(http://www.quartzscheduler.org). Both schedulers are set up
using a FactoryBean with optional references to Timers or Triggers, respectively.
Furthermore, a convenience class for both the Quartz Scheduler and the Timer is
available that allows you to invoke a method of an existing target object
(analogous to normal MethodInvokingFactoryBeans).

22.2. Using the OpenSymphony Quartz Scheduler

Quartz uses Triggers, Jobs and
JobDetail ro realize scheduling of all kinds of jobs.
For the basic concepts behind Quartz, have a look at
http://www.opensymphony.com/quartz. For convenience purposes,
Spring offers a couple of classes that simplify usage of Quartz within
Spring-based applications.

22.2.1. Using the JobDetailBean

JobDetail objects contain all information needed to
run a job. Spring provides a so-called JobDetailBean
that makes the JobDetail more of an actual JavaBean with sensible defaults.
Let's have a look at an example:

The job detail bean has all information it needs to run the job (ExampleJob).
The timeout is specified as the job data map. The job data map is
available through the JobExecutionContext (passed to you at execution time),
but the JobDetailBean also maps the properties from the
job data map to properties of the actual job. So in this case, if the ExampleJob contains
a property named timeout, the JobDetailBean will automatically apply it:

All additional settings from the job detail bean are of course available to you as well.

Note: Using the name and group properties,
you can modify the name and the group of the job, respectively. By default the name of
the job equals the bean name of the job detail bean (in the example above, this is
exampleJob).

22.2.2. Using the MethodInvokingJobDetailFactoryBean

Often you just need to invoke a method on a specific object. Using the
MethodInvokingJobDetailFactoryBean you can do exactly this:

Using the MethodInvokingJobDetailFactoryBean 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.

By default, Quartz Jobs are stateless, resulting in the possibility of jobs interfering
with each other. If you specify two triggers for the same JobDetail, it might be possible
that before the first job has finished, the second one will start. If JobDetail objects
implement the Stateful interface, this won't happen. The second job will not start before
the first one has finished. To make jobs resulting from the MethodInvokingJobDetailFactoryBean
non-concurrent, set the concurrent flag to false.

22.2.3. Wiring up jobs using triggers and the SchedulerFactoryBean

We've created job details, jobs and we've reviewed the convenience bean
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
SchedulerFactoryBean. Several triggers are available
within Quartz. Spring offers two subclassed triggers with convenient defaults:
CronTriggerBean and SimpleTriggerBean.

Triggers need to be scheduled. Spring offers a SchedulerFactoryBean exposing properties
to set the triggers. SchedulerFactoryBean schedules the actual jobs with those triggers.

22.3. Using JDK Timer support

The other way to schedule jobs in Spring is using JDK Timer objects.
More information about Timers themselves can be found at
http://java.sun.com/docs/books/tutorial/essential/threads/timer.html.
The concepts discussed above also apply to the Timer support. You can create
custom timers or use the timer that invokes methods. Wiring timers has to be done
using the TimerFactoryBean.

22.3.1. Creating custom timers

Using the TimerTask you can create customer timer tasks, similar to Quartz jobs:

The above example will result in the doIt being called on the
exampleBusinessObject (see below):

public class BusinessObject {
// properties and collaborators
public void doIt() {
// do the actual work
}
}

Changing the reference of the above example (in which the ScheduledTimerTask is mentioned)
to the doIt will result in this task being executed.

22.3.3. Wrapping up: setting up the tasks using the TimerFactoryBean

The TimerFactoryBean is similar to the Quartz SchedulerFactoryBean in that it serves the same
purpose: setting up the actual scheduling. The TimerFactoryBean sets up an actual Timer and
schedules the tasks it has references to. You can specify whether or not daemon threads should
be used.