Spring and Quartz: Multi-Job Scheduling Service
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.
it’s all great but I don’t see the point of all the comments which say the exact same thing as code.
Unable to download the file in step 12
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
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.