In many applications the need arises to perform a certain action at a given time without any user interaction, usually to perform some administrative tasks. These tasks need to be scheduled, say to perform a job in the early hours of the morning before the start of business. This functionality is provided by using job scheduling software. Quartz.NET is an excellent open source job scheduler that can be used for these purposes. It provides a wealth of features, such as persistent jobs and clustering. To find out more about Quartz.NET visit their web site. Spring integration allows you to use Spring to configure Quartz jobs, triggers, and schedulers and also provides integration with Spring's transaction management features.
The full details of Quartz are outside the scope of this quickstart
    but here is 'quick tour for the impatient' of the main classes and
    interfaces used in Quartz so you can get your sea legs. A Quartz
    IJob interface represents the task you would like to
    execute. You either directly implement Quartz's IJob
    interface or a convenience base class. The Quartz
    Trigger controls when a job is executed, for example in
    the wee hours of the morning every weekday . This would be done using
    Quartz's CronTrigger implementation. Instances of your
    job are created every time the trigger fires. As such, in order to pass
    information between different job instances you stash data away in a
    hashtable that gets passed to the each Job instance upon its creation.
    Quartz's JobDetail class combines the
    IJob and this hashtable of data. Instead of the
    standard System.Collections.Hashtable the class
    JobDataMap is used. Triggers are registered with a
    Quartz IScheduler implementation that manages the
    overall execution of the triggers and jobs. The
    StdSchedulerFactory implementation is generally
    used.
![]()  | Note | 
|---|---|
| 
       To follow this Quarts QuickStart load the solution file found in
      the directory
        | 
The sample application has two types of Jobs. One that inherits from
    Spring's convenience base class QuartzJobObject and
    another which does not inherit from any base class. The latter class is
    adapted by Spring to be a Job. Two triggers, one for each of the jobs, are
    created. These triggers are in turn registered with a scheduler. In each
    case the job implementation will write information to the console when it
    is executed.
The Spring base class QuartzJobObject implements
    IJob and allows for your object's properties to be set
    via values that are stored inside Quartz's JobDataMap
    that is passed along each time your job is instantiated due a trigger
    firing. This class is shown below
    public class ExampleJob : QuartzJobObject
    {
        private string userName;
        public string UserName
        {
            set { userName = value; }
        }
        protected override void ExecuteInternal(JobExecutionContext context)
        {
            Console.WriteLine("{0}: ExecuteInternal called, user name: {1}, next fire time {2}", 
                DateTime.Now, userName, context.NextFireTimeUtc.Value.ToLocalTime());
        }
    }
    The method ExecuteInternal is called when the
    trigger fires and is where you would put your business logic. The
    JobExecutionContext passed in lets you access various
    pieces of information about the current job execution, such as the
    JobDataMap or information on when the next time the trigger will fire. The
    ExampleJob is configured by creating a
    JobDetail object as shown below in the following XML
    snippet taken from spring-objects.xml
  <object name="exampleJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
    <property name="JobType" value="Spring.Scheduling.Quartz.Example.ExampleJob, Spring.Scheduling.Quartz.Example" />
    <!-- We can inject values through JobDataMap -->
    <property name="JobDataAsMap">
      <dictionary>
        <entry key="UserName" value="Alexandre" />
      </dictionary>
    </property>
  </object>
    The dictionary property of the JobDetailObject,
    JobDataAsMap, is used to set the values of the
    ExampleJob's properties. This will result in the ExampleJob being
    instantiated with it's UserName property value set to 'Alexandre' the
    first time the trigger fires.
We then will schedule this job to be executed on 20 second
    increments of every minute as shown below using Spring's
    CronTriggerObject which creates a Quartz
    CronTrigger.
  <object id="cronTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz">
    <property name="jobDetail" ref="exampleJob" />
    <!-- run every 20 second of minute -->
    <property name="cronExpressionString" value="0/20 * * * * ?" />
  </object>
    Lastly, we schedule this trigger with the scheduler as shown below
  <object type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
    <property name="triggers">
      <list>
        <ref object="cronTrigger" />
      </list>
    </property>
  </object>
    Running this configuration will produce the following output
8/8/2008 1:29:40 PM: ExecuteInternal called, user name: Alexandre, next fire time 8/8/2008 1:30:00 PM 8/8/2008 1:30:00 PM: ExecuteInternal called, user name: Alexandre, next fire time 8/8/2008 1:30:20 PM 8/8/2008 1:30:20 PM: ExecuteInternal called, user name: Alexandre, next fire time 8/8/2008 1:30:40 PM
It is very convenient to schedule the execution of method as a job. The AdminService class in the example demonstrates this functionality and is listed below.
    public class AdminService
    {
        private string userName;
        public string UserName
        {
            set { userName = value; }
        }
        public void DoAdminWork()
        {
            Console.WriteLine("{0}: DoAdminWork called, user name: {1}", DateTime.Now, userName);
        }
    }
    Note that it does not inherit from any base class. To instruct
    Spring to create a JobDetail object for this method we
    use Spring's factory object class
    MethodInvokingJobDetailFactoryObject as shown
    below
  <object id="adminService" type="Spring.Scheduling.Quartz.Example.AdminService, Spring.Scheduling.Quartz.Example">
    <!-- we inject straight to target object -->
    <property name="UserName" value="admin-service" />
  </object>
  
  <object id="jobDetail" type="Spring.Scheduling.Quartz.MethodInvokingJobDetailFactoryObject, Spring.Scheduling.Quartz">
    <!-- We don't actually need to implement IJob as we can use delegation -->
    <property name="TargetObject" ref="adminService" />
    <property name="TargetMethod" value="DoAdminWork" />
  </object>
    Note that AdminService object is configured using
    Spring as you would do normally, without consideration for Quartz. The
    trigger associated with the jobDetail object is listed below. Also note
    that when using MethodInvokingJobDetailFactoryObject you can't use
    database persistence for Jobs. See the class documentation for additional
    details.
  <object id="simpleTrigger" type="Spring.Scheduling.Quartz.SimpleTriggerObject, Spring.Scheduling.Quartz">
    <!-- see the example of method invoking job above -->
    <property name="jobDetail" ref="jobDetail" />
    <!-- 5 seconds -->
    <property name="startDelay" value="5s" />
    <!-- repeat every 5 seconds -->
    <property name="repeatInterval" value="5s" />
  </object>
    This creates an instances of Quartz's SimpleTrigger class (as
    compared to its CronTrigger class used in the previous section).
    StartDelay and RepeatInterval
    properties are TimeSpan objects than can be set using the convenient
    strings such as 10s, 1h, etc, as supported by Spring's custom
    TypeConverter for TimeSpans.
This trigger can then be added to the scheduler's list of registered triggers as shown below.
  <object type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
    <property name="triggers">
      <list>
        <ref object="cronTrigger" />
        <ref object="simpleTrigger" />
      </list>
    </property>
  </object>
    The interleaved output of both these jobs being triggered is shown below.
8/8/2008 1:40:18 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:20 PM: ExecuteInternal called, user name: Alexandre, next fire time 8/8/2008 1:40:40 PM 8/8/2008 1:40:23 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:28 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:33 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:38 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:40 PM: ExecuteInternal called, user name: Alexandre, next fire time 8/8/2008 1:41:00 PM 8/8/2008 1:40:43 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:48 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:53 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:40:58 PM: DoAdminWork called, user name: Gabriel 8/8/2008 1:41:00 PM: ExecuteInternal called, user name: Alexandre, next fire time 8/8/2008 1:41:20 PM 8/8/2008 1:41:03 PM: DoAdminWork called, user name: Gabriel