Tuesday, December 13, 2011

Spring + Quartz step-by-step

Update: 08/03/2016 - There is much easier way these days to quickly set up a scheduled process in your Java/Spring app - checkout the "@Scheduled" Spring annotation. The steps below could still be of help to you, if you are stuck with an older Spring version, which does not support the @Scheduled annotation.

I often end up spending prohibitive amount of time on tasks which I have completed in the past. One such task is setting up batch job with Spring and Quartz. Here is a step-by-step for my own sake or for anyone's else's sake:
The scenario is to have a job that periodically polls blogs for new blog entries. I assume a maven project.

1. Code up your job:

package com.qsi.template.util;


import java.net.URL;
import java.util.Arrays;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class FeedReader {
String [] feedsUrls = new String [] { "http://boyko11.blogspot.com/feeds/posts/default" };
    public void readFeeds() {
    for (String feedUrlAsString: Arrays.asList(feedsUrls)) {
       try {
           URL feedUrl = new URL(feedUrlAsString);
           SyndFeedInput input = new SyndFeedInput();
           SyndFeed feed = input.build(new XmlReader(feedUrl));
           SyndEntry mostRecentEntry = (SyndEntryImpl) feed.getEntries().get(0);
           System.out.println("title: " + mostRecentEntry.getTitle());
           System.out.println("author: " + mostRecentEntry.getAuthor());
           System.out.println("date: " +  mostRecentEntry.getPublishedDate());
           System.out.println("link: " + mostRecentEntry.getLink());
       }
       catch (Exception ex) {
           ex.printStackTrace();
           System.out.println("ERROR: "+ex.getMessage());
       }
   }
}
}

I am using Rome for RSS reading :http://java.net/projects/rome/

2. Add dependencies to pom.xml


<dependency>
   <groupId>org.opensymphony.quartz</groupId>
   <artifactId>quartz</artifactId>
   <version>${quartz.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>

3. Add the job to your Spring config file(in my case applicationContext.xml)

<bean id="feedReader" class="com.qsi.template.util.FeedReader" />


<bean id="feedReaderJob"     class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="feedReader" />
<property name="targetMethod" value="readFeeds" />
</bean>




4. Add a trigger to you Spring config file


<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">

<property name="jobDetail" ref="feedReaderJob" />
<property name="repeatInterval" value="10000" />
<property name="startDelay" value="3000" />

</bean>

This job will trigger 3 seconds after the app starts and will run every 10 seconds

5. Add Scheduler to your Spring config file


<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<property name="jobDetails">
<list>
<ref bean="feedReaderJob" />
</list>
</property>

<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>

That should be it.

Credits:
http://www.mkyong.com/spring/spring-quartz-scheduler-example/

The mkyong example also has an example with the CronTriggerBean which might be more desirable to use in your actual production apps.

Hope this helps someone! Cheers!

Update: Since this example lacks context, I added an web app example:
web app example

Update: 12-11-2013: There's a better way to do a scheduled job these days. Use the @Scheduled annotation.

6 comments:

  1. Nice job! I'll use this to setup my next spring/quartz cron replacement.

    ReplyDelete
  2. Great job Boyko, thanks for the post!

    ReplyDelete
  3. Good example! I am new to the spring batch job and quartz. I just have a question. How to run the project using maven?

    ReplyDelete
    Replies
    1. Hi,
      Maven is just a build tool. In my case it is just being used to manage dependencies and to make the WAR file. You don't really need maven to use Spring Batch and Quartz.
      You'd do your coding, you'd make sure the code is in the WAR and you'd just deploy the war to whatever server you are using. If you are using Eclipse or another IDE, you wouldn't even have to worry about putting a WAR together, you'd just use the IDE to deploy to whatever server you have. If you are specifically asking on how to run any web project with maven I'd look into: https://wiki.base22.com/display/btg/How+to+create+a+Maven+web+app+and+deploy+to+Tomcat+-+fast
      Hope this helps!

      Delete
  4. Kiến thức của Admin rất hay, cám ơn chị đã share.
    Thông tin thêm : Tỳ hưu

    ReplyDelete