Spring and Quartz: Multi-Job Scheduling Service

Job Scheduling is so important requirement for the applications. Especially in large-scale projects, working with a lot of jobs can be a problem. Spring and Quartz have brought significant benefits for the solution of this problem. This article shows how to schedule multi jobs easily by using Spring and Quartz.

Used Technologies :

JDK 1.6.0_21
Spring 3.1.1
Quartz 1.8.5
Maven 3.0.2

STEP 1 : CREATE MAVEN PROJECT
A maven project is created as below. (It can be created by using Maven or IDE Plug-in)

STEP 2 : LIBRARIES
Spring dependencies are added to Maven’ s pom.xml.

<!-- Spring 3 dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
</dependency>

STEP 3 : CREATE TASK CLASSES
A FirstTask Class is created.

package com.otv.task;
 
import org.apache.log4j.Logger;
 
/**
 * First Task
 *
 * @author  onlinetechvision.com
 * @since   24 Feb 2012
 * @version 1.0.0
 *
 */
public class FirstTask {
 
    private static Logger log = Logger.getLogger(FirstTask.class);
 
    /**
     * Execute this task
     *
     */
    public void execute() {
        log.debug("FirstTask runs successfully...");
    }
}

A SecondTask Class is created.

package com.otv.task;
 
import org.apache.log4j.Logger;
 
/**
 * Second Task
 *
 * @author  onlinetechvision.com
 * @since   24 Feb 2012
 * @version 1.0.0
 *
 */
public class SecondTask {
 
    private static Logger log = Logger.getLogger(SecondTask.class);
 
    /**
     * Execute this task
     *
     */
    public void execute() {
        log.debug("SecondTask runs successfully...");
    }
}

STEP 4 : CREATE ISchedulerService INTERFACE
ISchedulerService Interface is created.

package com.otv.service;
 
/**
 * Scheduler Service Interface
 *
 * @author  onlinetechvision.com
 * @since   24 Feb 2012
 * @version 1.0.0
 *
 */
public interface ISchedulerService {
 
    /**
     * Execute First Task
     *
     * @param
     * @throws
     * @return
     */
    public void executeFirstTask();
 
    /**
     * Execute Second Task
     *
     * @param
     * @throws
     * @return
     */
    public void executeSecondTask();
}

STEP 5 : CREATE SchedulerService CLASS
SchedulerService Class is created by implementing ISchedulerService Interface. This service schedules tasks.

package com.otv.service;
 
import com.otv.task.FirstTask;
import com.otv.task.SecondTask;
 
/**
 * Scheduler Service Implementation
 *
 * @author  onlinetechvision.com
 * @since   24 Feb 2012
 * @version 1.0.0
 *
 */
public class SchedulerService implements ISchedulerService {
 
    private FirstTask  firstTask;
    private SecondTask secondTask;
 
    /**
     * Execute First Task
     *
     */
    public void executeFirstTask() {
        getFirstTask().execute();
    }
 
    /**
     * Execute Second Task
     *
     */
    public void executeSecondTask() {
        getSecondTask().execute();
    }
 
    /**
     * Get First Task
     *
     * @return FirstTask
     */
    public FirstTask getFirstTask() {
        return firstTask;
    }
 
    /**
     * Set First Task
     *
     * @param  firstTask First Task
     */
    public void setFirstTask(FirstTask firstTask) {
        this.firstTask = firstTask;
    }
 
    /**
     * Get Second Task
     *
     * @return SecondTask
     */
    public SecondTask getSecondTask() {
        return secondTask;
    }
 
    /**
     * Set Second Task
     *
     * @param  secondTask Second Task
     */
    public void setSecondTask(SecondTask secondTask) {
        this.secondTask = secondTask;
    }
}

STEP 6 : CREATE Application CLASS
Application Class is created. This class runs the application.

package com.otv.starter;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
 * Application Starter Class
 *
 * @author  onlinetechvision.com
 * @since   24 Feb 2012
 * @version 1.0.0
 *
 */
public class Application {
 
    /**
     * Main method of the Application
     *
     */
    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}

STEP 7 : DEFINE Job Detail CONFIGURATIONS
Job Details can be defined via two ways in Spring. By using MethodInvokingJobDetailFactoryBean or by extending QuartzJobBean. In this example, MethodInvokingJobDetailFactoryBean method has been used. targetObject and targetMethod properties are given to MethodInvokingJobDetailFactoryBean.

<!-- Job Details-->
<bean id="FirstTaskJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="SchedulerService" />
    <property name="targetMethod" value="executeFirstTask" />
</bean>
 
<bean id="SecondTaskJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="SchedulerService" />
    <property name="targetMethod" value="executeSecondTask" />
</bean>

STEP 8 : DEFINE Trigger CONFIGURATIONS
Triggers can also be defined via two ways in Spring. By defining SimpleTriggerBean or CronTriggerBean . When SimpleTriggerBean is used, jobDetail, repeatInterval and startDelay properties are defined. When CronTriggerBean is used, jobDetail and cronExpression properties are defined. In this example, repeat interval of first task has been set 5 secs and repeat interval of second task has been set 12 secs .

<!-- Simple Trigger -->
<bean id="FirstSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="FirstTaskJobDetail" />
    <property name="repeatInterval" value="5000" />
    <property name="startDelay" value="1000" />
</bean>
 
<!-- <bean id="SecondSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        <property name="jobDetail" ref="SecondTaskJobDetail" />
        <property name="repeatInterval" value="12000" />
        <property name="startDelay" value="1000" />
    </bean> -->   
 
<!-- Cron Trigger -->
<bean id="SecondSimpleTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="SecondTaskJobDetail" />
    <property name="cronExpression" value="0/12 * * * * ?" />
</bean>

STEP 9 : DEFINE SchedulerFactoryBean CONFIGURATION
Finally, Job Details and Triggers are configured by creating SchedulerFactoryBean.

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="jobDetails">
       <list>
          <ref bean="FirstTaskJobDetail" />
          <ref bean="SecondTaskJobDetail" />
       </list>
    </property>
    <property name="triggers">
       <list>
          <ref bean="FirstSimpleTrigger" />
          <ref bean="SecondSimpleTrigger" />
       </list>
    </property>
</bean>

STEP 10 : CREATE applicationContext.xml
All applicationContext.xml content is shown as below.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
    <!-- Beans Declaration -->
    <bean id="FirstTask" class="com.otv.task.FirstTask"></bean>
    <bean id="SecondTask" class="com.otv.task.SecondTask"></bean>
 
    <bean id="SchedulerService" class="com.otv.service.SchedulerService">
        <property name="firstTask" ref="FirstTask" />
        <property name="secondTask" ref="SecondTask" />
    </bean>
 
    <!-- Job Details-->
    <bean id="FirstTaskJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="SchedulerService" />
        <property name="targetMethod" value="executeFirstTask" />
    </bean>
 
    <bean id="SecondTaskJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="SchedulerService" />
        <property name="targetMethod" value="executeSecondTask" />
    </bean>
 
    <!-- Simple Trigger -->
    <bean id="FirstSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        <property name="jobDetail" ref="FirstTaskJobDetail" />
        <property name="repeatInterval" value="5000" />
        <property name="startDelay" value="1000" />
    </bean>
<!--
    <bean id="SecondSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        <property name="jobDetail" ref="SecondTaskJobDetail" />
        <property name="repeatInterval" value="12000" />
        <property name="startDelay" value="1000" />
    </bean>
-->
    <!-- Cron Trigger -->
    <bean id="SecondSimpleTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="SecondTaskJobDetail" />
        <property name="cronExpression" value="0/12 * * * * ?" />
    </bean>
 
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobDetails">
           <list>
              <ref bean="FirstTaskJobDetail" />
              <ref bean="SecondTaskJobDetail" />
           </list>
        </property>
        <property name="triggers">
           <list>
              <ref bean="FirstSimpleTrigger" />
              <ref bean="SecondSimpleTrigger" />
           </list>
        </property>
    </bean>
 
</beans>

STEP 11 : RUN PROJECT
After Application Class is started, below output logs will be shown :

25.02.2012 00:17:18 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:23 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:24 DEBUG (SecondTask.java:22) - SecondTask runs successfully...
25.02.2012 00:17:28 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:33 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:36 DEBUG (SecondTask.java:22) - SecondTask runs successfully...
25.02.2012 00:17:38 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:43 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:48 DEBUG (SecondTask.java:22) - SecondTask runs successfully...
25.02.2012 00:17:48 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:53 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:17:58 DEBUG (FirstTask.java:23) - FirstTask runs successfully...
25.02.2012 00:18:00 DEBUG (SecondTask.java:22) - SecondTask runs successfully...

STEP 12 : DOWNLOAD

OTV_SpringQuartz_MultiJobScheduling

Reference: Multi-Job Scheduling Service by using Spring and Quartz from our JCG partner Eren Avsarogullari at the Online Technology Vision blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

4 Responses to "Spring and Quartz: Multi-Job Scheduling Service"

  1. it’s all great but I don’t see the point of all the comments which say the exact same thing as code.

  2. Hidayath says:

    Unable to download the file in step 12

  3. Mirza Gaush says:

    Thank you much for a good tutorial. It gives a good insight about Spring+Quartz implementation but it has got few redundant code,
    47
    48
    49
    50
    51
    52

    As the defined jobs are already referenced in JobTriggers and hence it does not require to be defined in SchedulerFactory Configuration

  4. Renzo says:

    I’m a rookie with spring and quartz too , I’ve had a lot of problems trying to do a simple example of this. Thanks a lot.

Leave a Reply


4 − = three



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close