Spring 3 + Quartz 1.8.6 scheduler example
Updated on 25 July 2012 – Upgrade article to use Spring 3 and Quartz 1.8.6 (it was Spring 2.5.6 and Quartz 1.6)
In this tutorial, we will show you how to integrate Spring with Quartz scheduler framework. Spring comes with many handy classes to support Quartz, and decouple your class to Quartz APIs.
Tools Used :
- Spring 3.1.2.RELEASE
- Quartz 1.8.6
- Eclipse 4.2
- Maven 3
Currently, Spring 3 is still NOT support Quartz 2 APIs, see this SPR-8581 bug report. Will update this article again once bug fixed is released.
1. Project Dependency
You need following dependencies to integrate Spring 3 and Quartz 1.8.6
File : pom.xml
... <dependencies> <!-- Spring 3 dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.1.2.RELEASE</version> </dependency> <!-- QuartzJobBean in spring-context-support.jar --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.1.2.RELEASE</version> </dependency> <!-- Spring + Quartz need transaction --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>3.1.2.RELEASE</version> </dependency> <!-- Quartz framework --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>1.8.6</version> </dependency> </dependencies> ...
2. Scheduler Task
Create a normal Java class, this is the class you want to schedule in Quartz.
File : RunMeTask.java
package com.mkyong.common; public class RunMeTask { public void printMe() { System.out.println("Spring 3 + Quartz 1.8.6 ~"); } }
3. Declare Quartz Scheduler Job
With Spring, you can declare Quartz job in two ways :
3.1 MethodInvokingJobDetailFactoryBean
This is the simplest and straightforward method, suitable for simple scheduler.
<bean id="runMeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="runMeTask" /> <property name="targetMethod" value="printMe" /> </bean>
3.2 JobDetailBean
The QuartzJobBean is more flexible and suitable for complex scheduler. You need to create a class extends the Spring’s QuartzJobBean, and define the method you want to schedule in executeInternal() method, and pass the scheduler task (RunMeTask) via setter method.
File : RunMeJob.java
package com.mkyong.common; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; public class RunMeJob extends QuartzJobBean { private RunMeTask runMeTask; public void setRunMeTask(RunMeTask runMeTask) { this.runMeTask = runMeTask; } protected void executeInternal(JobExecutionContext context) throws JobExecutionException { runMeTask.printMe(); } }
Configure the target class via jobClass and method to run via jobDataAsMap.
<bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.mkyong.common.RunMeJob" /> <property name="jobDataAsMap"> <map> <entry key="runMeTask" value-ref="runMeTask" /> </map> </property> </bean>
4. Trigger
Configure Quartz trigger to define when will run your scheduler job. Two type of triggers are supported :
4.1 SimpleTrigger
It allows to set the start time, end time, repeat interval to run your job.
<!-- Simple Trigger, run every 5 seconds --> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="runMeJob" /> <property name="repeatInterval" value="5000" /> <property name="startDelay" value="1000" /> </bean>
4.2 CronTrigger
It allows Unix cron expression to specify the dates and times to run your job.
<!-- Cron Trigger, run every 5 seconds --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="runMeJob" /> <property name="cronExpression" value="0/5 * * * * ?" /> </bean>
The Unix cron expression is highly flexible and powerful, read more in following websites :
5. Scheduler Factory
Create a Scheduler factory bean to integrate both job detail and trigger together.
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobDetails"> <list> <ref bean="runMeJob" /> </list> </property> <property name="triggers"> <list> <ref bean="simpleTrigger" /> </list> </property> </bean>
6. Spring Bean Configuration File
Complete Spring’s bean configuration file.
File : Spring-Quartz.xml
<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"> <bean id="runMeTask" class="com.mkyong.common.RunMeTask" /> <!-- Spring Quartz --> <bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.mkyong.common.RunMeJob" /> <property name="jobDataAsMap"> <map> <entry key="runMeTask" value-ref="runMeTask" /> </map> </property> </bean> <!-- <bean id="runMeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="runMeTask" /> <property name="targetMethod" value="printMe" /> </bean> --> <!-- Simple Trigger, run every 5 seconds --> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="runMeJob" /> <property name="repeatInterval" value="5000" /> <property name="startDelay" value="1000" /> </bean> <!-- Cron Trigger, run every 5 seconds --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="runMeJob" /> <property name="cronExpression" value="0/5 * * * * ?" /> </bean> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobDetails"> <list> <ref bean="runMeJob" /> </list> </property> <property name="triggers"> <list> <ref bean="simpleTrigger" /> </list> </property> </bean> </beans>
7. Demo
Run it ~
package com.mkyong.common; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main( String[] args ) throws Exception { new ClassPathXmlApplicationContext("Spring-Quartz.xml"); } }
Output to console.
Jul 25, 2012 3:23:09 PM org.springframework.scheduling.quartz.SchedulerFactoryBean startScheduler INFO: Starting Quartz Scheduler now Spring 3 + Quartz 1.8.6 ~ //run every 5 seconds Spring 3 + Quartz 1.8.6 ~

Simple, well explained and functional. I have lost the count of the times I ended up in your blog looking for answers.
Thanks!
I fully agree with Gullermo.
Thanks! and keep the posts comming ;)
Nice example. Helped a lot. Thanks.
Excellent post, thanks!!!!!
Thank you !!!
Hi mkyong,
Your articles have always been a great help for me.
Thank you so much!
Hi mkyong,
I’m always follows your articles, it’s awesome to learn new things. i have one problem and I’m using spring with Quartz and every
thing working fine but some previous cofigured
triggers also got executed because they are stored
in Quartz tables. Manually we can delete all
un configured triggers and execute the application
but that is not a good practice, right? so i want to
remove all the triggers through any spring+quartz property
or some other solution , i think there is spring+quartz
property for this problem.but If any property is available
to handle this problem and if you know plz forward me your
valuable solution .
Actually the scenario is ,
suppose when i have configured 3 triggers in spring configuration file like
when server started all the triggers stored in Quartz tables with
corresponding cron triggers and job details. But if i
remove any of the trigger in my configuration like in above for example i removed second Trigger , one thing i removed that trigger from coniguration file only but not
from Quartz tables. at that time DBtrigger (removed trigger)
also executed. How to avoid that problem. can anyone help to me.
it’s very useful to me. i googled lot of sites but i didn’t
get a solution. In spring + Quartz integration , is there
any property is there to handle this problem or we need to
do some thing for this problem.
Please tell me if you know the solution.
Thanks in advance.
Hi mkyong,
I am facing a problem with Quartz+Spring implementation in my project. My production environment is clustered i.e two jboss instances. Therefore the time at which the job is scheduled say at 5PM, the same from each server instance gets triggered, therefore causing duplicate runs of the same job. How do I ensure that only one job instance runs in a clustered environment?
Thanks and regards,
KB.
Hi KB,
The simplest way:
You may use a flag in your database to indicate if a proccess has begun or not.
Other ways:
Use serializable objects, if possible, and try avoid static variables;
Multithread may be controlled by the package java.util.concurrent, but depends on your scenario and JDK version.