Home > Quartz, Spring > Integrating Quartz with Spring

Integrating Quartz with Spring

Spring’s reference documentation goes over in detail on integrating Quartz with Spring. However, the technique requires extending Spring’s QuartzJobBean class. Here are steps for achieving the same integration with out dependencies on QuartzJobBean class:

Step 1: Create the Quartz job that needs to be scheduled. Here is a simple Hello world job class:

public class HelloWorldJob implements Job
{
  public void execute(JobExecutionContext jobExecutionContextthrows JobExecutionException
  {
    System.out.println("Hello World");
  }
}
Notice that we are simply implementing org.quartz.Job interface.

Step 2: In the Spring’s context file, define a JobDetail bean for this job. A JobDetail contains metadata for the job such as the group a job would belong to etc.

<?xml version=”1.0″ encoding=”UTF-8″?>
 <beans xmlns=”http://www.springframework.org/schema/beans” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
   xmlns:p=”http://www.springframework.org/schema/p” xmlns:context=”http://www.springframework.org/schema/context
   xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd“>
 
 <bean id=”helloWorldJobDetail” class=”org.quartz.JobDetail”>
      <property name=”name” value=”helloWorldJobDetail” />
      <property name=”jobClass” value=”local.quartz.job.HelloWorldJob” />
 </bean>

Step 3: Again, in the context file, define a Trigger that would trigger the job execution. For simplicity sake, lets use a SimpleTrigger. More about triggers can be found in the Quartz documentation:

 <bean id=”simpleTrigger” class=”org.quartz.SimpleTrigger”>
     <property name=”name” value=”simpleTrigger” />
     <property name=”jobName” value=”helloWorldJobDetail” />
     <property name=”startTime”>
       <bean class=”java.util.Date” />   
     </property>
  </bean>

The startTime property is set to “now” which means that the job will run as soon as the spring completes bean loading.

Step 4: Finally, define a SchedulerFactoryBean that sets up the Quartz scheduler:

<bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
     <property name=”jobDetails”>
        <list> <ref bean=”helloWorldJobDetail” /> </list>
     </property>
     <property name=”triggers”>
        <list> <ref bean=”simpleTrigger” /> </list>
     </property>
 </bean>

Notice that this is the only Spring class used in the configuration. When the application loads the Spring context, the job should run and print “Hello World”

In most cases, the job instances rely on external services to perform their job (such as an email service to send out email). These external components can be easily made available to the job instances via dependency injection. Let’s modify the above class to display a custom message:

 public class HelloWorldJob implements Job
{
  private String message;
  
  public void setMessage(String message)
  {
    this.message = message;
  }
  
  public void execute(JobExecutionContext jobExecutionContextthrows JobExecutionException
  {
    System.out.println(message);
  }
}

Next, in the Spring context file, add a bean that contains the custom message we want to display:

<bean id=”message” class=”java.lang.String”>
  <constructor-arg value=”Hello Again!!” />
 </bean>

With Quartz 1.5 and above, dependency Injection into Quartz jobs can be done via a JobFactory instance. Here are the modifications that need to be done to the Spring context:

<bean id=”jobFactory” class=”org.springframework.scheduling.quartz.SpringBeanJobFactory” />
 
 <bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
      <property name=”jobFactory” ref=”jobFactory” />
      <property name=”schedulerContextAsMap”>
          <map> <entry key=”message” value-ref=”message” /> </map>   
      </property>
      <property name=”jobDetails”>
         <list> <ref bean=”helloWorldJobDetail” /> </list>
      </property>
      <property name=”triggers”>
        <list> <ref bean=”simpleTrigger” /> </list>
       </property>
  </bean>

Now when the Spring context gets loaded, the job should run and print “Hello Again!!”.

Categories: Quartz, Spring Tags: ,
  1. Sweety
    July 31st, 2009 at 13:22 | #1

    Hello Balaji,

    I used your blog as example in one of my project. Can you please post more blogs on Quartz job?

    Thanks,
    Sweety

  2. September 15th, 2009 at 07:20 | #2

    You neither have to extend Springs QuartzJobBean nor the Job Interface of Quartz.
    You can write the Job as a simple POJO. Then you have to configure it as Spring Bean und use Springs MethodInvokingJobDetailFactoryBean to get it running as a Job.

    Just read the reference documentation. Its all in there. ;-)

  3. Balaji
    September 15th, 2009 at 09:27 | #3

    I agree that MethodInvokingJobDetailFactoryBean is very convenient and you don’t have to extend any class or implement an interface.

    However, there are cases where using MethodInvokingJobDetailFactoryBean might not be sufficient. For example, it is not suitable when working with a persistent job store.

  4. Pradeep Kumar
    February 16th, 2010 at 04:10 | #4

    Hi Balaji,

    This is Pradeep Kumar. Your Examples with simple definition is pretty good. I need more quartz examples. If possible can you post more article about Quartz like how it will work with Spring+Hibernate+JDBCJobStore with a simple example. It will be easier for me and all who are looking for Quartz.

    Thanks in advance

  5. Anyz
    February 23rd, 2010 at 03:51 | #5

    I changed you code to use CronTrigger and make it fire every 30 seconds. But When running code the job gets executed twice. I could not figure out why its running twice against each fire of trigger.

  6. Balaji
    February 23rd, 2010 at 09:44 | #6

    Anyz, What cron expression are you using?

  7. Vaibhav
    January 30th, 2011 at 22:51 | #7

    Hello Anyz did you find cause job was running twice i am running in to same issue, In fact i have job which runs every 10 minutes but some how it is running twice. My cron expression is

  8. Rabindra Singh
    June 9th, 2011 at 02:00 | #8

    Hi.
    I am highly impressed by this blog. This gives a lot of information about Quartz with Spring. I have also visited following link i.e. giving similarly good information about Quartz framework and its integration with both JSP, Servlet and also with Spring Framework. The links are:
    Quartz integration with JSP,Servlet:
    http://jksnu.blogspot.com/2011/03/quartz-framework-implementation-with.html

    Quartz integration with Spring:
    http://jksnu.blogspot.com/

  9. August 22nd, 2011 at 05:57 | #9

    Hi all.
    In my case the job was run twice (or multiple times) because my cron expression was wrong. I had specified * for seconds which caused my job to run multiple times within one minute. As soon as I had 0 instead of * it worked fine, because my job needed more than one second to execute once. If you are not sure whether your job runs long enough, just add a Thread.sleep(1000); to your job.
    Rgds,
    Axel

  10. May 11th, 2012 at 13:56 | #10

    Awesome……this was the first blog that nicely explained it the way it needs to! This works

  1. No trackbacks yet.