# Scheduling and Thread Pooling

## Introduction

The Spring Framework features integration classes for scheduling support. Currently, Spring supports the Quartz Scheduler (). The scheduler is set up using a `IFactoryObject` with optional references to `Trigger` instances, respectively. Furthermore, a convenience class for the Quartz Scheduler is available that allows you to invoke a method of an existing target object.

## Using the Quartz.NET Scheduler

Quartz uses `Trigger`, `Job` and `JobDetail` objects to realize scheduling of all kinds of jobs. For the basic concepts behind Quartz, have a look at . For convenience purposes, Spring offers a couple of classes that simplify the usage of Quartz within Spring-based applications.

### Using the JobDetailObject

`JobDetail` objects contain all information needed to run a job. The Spring Framework provides a `JobDetailObject` that makes the `JobDetail` easier to configure and with sensible defaults. Let's have a look at an example:

    <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>

The job detail object has all information it needs to run the job (`ExampleJob`). The timeout is specified in the job data dictionary. The job data dictonary is available through the `JobExecutionContext` (passed to you at execution time), but the `JobDetailObject` 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 `JobDetailObject` will automatically apply it:

    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) {
          // do the actual work
      }
    }

All additional settings from the job detail object 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 matches the object name of the job detail object (in the example above, this is `ExampleJob`).

### Using the `MethodInvokingJobDetailFactoryObject`

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

    <object id="JobDetail" type="Spring.Scheduling.Quartz.MethodInvokingJobDetailFactoryObject, Spring.Scheduling.Quartz">
      <property name="TargetObject" ref="ExampleBusinessObject" />
      <property name="TargetMethod" value="DoIt" />
    </object>

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

    public class ExampleBusinessObject {

      // properties and collaborators

      public void DoIt() {
        // do the actual work
      }
    }

    <object id="ExampleBusinessObject" type="Examples.BusinessObjects.ExampleBusinessObject, Examples.BusinessObjects"/>

Using the `MethodInvokingJobDetailFactoryObject`, 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` classes 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 `MethodInvokingJobDetailFactoryObject` non-concurrent, set the `concurrent` flag to `false`.

    <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>

By default, jobs will run in a concurrent fashion.

Also note that when using MethodInvokingJobDetailFactoryObject you can't use database persistence for Jobs. See the class documentation for additional details.

### Wiring up jobs using triggers and the `SchedulerFactoryObject`

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 `SchedulerFactoryObject`. Several triggers are available within Quartz. Spring offers two subclassed triggers with convenient defaults: `CronTriggerObject` and `SimpleTriggerObject`

Triggers need to be scheduled. Spring offers a `SchedulerFactoryObject` that exposes triggers to be set as properties. `SchedulerFactoryObject` schedules the actual jobs with those triggers.

Find below a couple of examples:

    <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>

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 `SchedulerFactoryObject`:

    <object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
        <property name="triggers">
            <list>
                <ref object="CronTrigger" />
                <ref object="SimpleTrigger" />
            </list>
        </property>
    </object>

More properties are available for the `SchedulerFactoryObjecct` for you to set, such as the calendars used by the job details, properties to customize Quartz with, etc. Have a look at the SchedulerFactoryObject SDK docs for more information.