Build Scheduler Application with OpenSymphony Quartz in Spring favour

Spring features integration classes for scheduling support. Currently, Spring supports OpenSymphony Quartz, which can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs

 

OpenSymphony  Quartz

Quartz introduced the JobDetails and Trigger concept to handle the scheduler. In which, Trigger objects are used to trigger the execution (or ‘firing’) of jobs and The JobDetail object is created by the Quartz client (your program) at the time the Job is added to the scheduler

 

Why Jobs AND Triggers? Many job schedulers do not have separate notions of jobs and triggers. Some define a ‘job’ as simply an execution time (or schedule) along with some small job identifier. Others are much like the union of Quartz’s job and trigger objects. While developing Quartz, we decided that it made sense to create a separation between the schedule and the work to be performed on that schedule. This has (in our opinion) many benefits.

 

Other main objects will be introduced will be introduced in the following paragraph.

 

Quartz in Spring

Spring’s Quartz API resides in the org.springframework.scheduling.quartz package.  It provides wrapper classes that extend or implement all the main classes/interfaces respectively.

OpenSymphony  Quartz

Quartz in Spring

Job

QuartzJobBean

JobDetail

JobDetailBean

CronTrigger

CronTriggerBean

SimpleTrigger

SimpleTriggerBean

SchedulerFactory

SchedulerFactoryBean

 

 

 

 

 

 

 

 

 

 

QuartzJobBean implements org.quartz.Job interface. Your scheduled jobs will be executed within this class.

 

The JobDetail contains various property settings for the Job, as well as a JobDataMap, which can be used to store state information for a given instance of your job class. (While a class that you implement is the actual "job", Quartz needs to be informed about various attributes that you may wish the job to have. This is done via the JobDetail class)

 

SimpleTriggerBean and CronTriggerBean are both extends from Trigger class and responsible SimpleTrigger is handy if you need ‘one-shot’ execution (just single execution of a job at a given moment in time), or if you need to fire a job at a given time, and have it repeat N times, with a delay of T between executions. CronTrigger is useful if you wish to have triggering based on calendar-like schedules – such as "every Friday, at noon" or "at 10:15 on the 10th day of every month.

 

SchedulerFactoryBean that creates and configures a Quartz Scheduler, manages its lifecycle as part of the Spring application context, and exposes the Scheduler as bean reference for dependency injection. It allows registration of JobDetails, Calendars and Triggers, automatically starting the scheduler on initialization and shutting it down on destruction. In scenarios that just require static registration of jobs at startup, there is no need to access the Scheduler instance itself in application code.

 

Configuration

Once you get into the Spring Quartz, you would find it you a lot less to write in your code, but having most of the work in the configuration file.

 

Let’s declare your customised JobDetail class.

<bean id="myJob" class="com.hongliang.quartz.MyJobDetail" scope="prototype" lazy-init="false">

    <property name="jobClass" value="com.hongliang.quartz.JobExcuter"/>

    <property name="name" value="my_job"/>

    <property name="beanName" value="my_job"/>

    <property name="myMessage" value="First Message"/>

    <property name="jobListenerNames" value="my_job_listener"/>

</bean>

 

JobExcuter is class that extends QuartzJobBean and where you have your scheduled jobs to be called to execute.  If you want to print a message held by the DataMap to the log file, you can write something like this.

public void executeInternal(JobExecutionContext exeContext) throws JobExecutionException {

    JobDataMap data = exeContext.getJobDetail().getJobDataMap();

LOGGER.debug(“Listener Added Message: " + data.get("MessageAddedFromListerner"));

}

 

jobListenerNames Set a list of JobListener names for this job, referring to non-global JobListeners registered with the Scheduler.

 

    <bean id="myJobListener" class="com.hongliang.quartz.MyJobListener">

        <property name="name" value="my_job_listener"/>

    </bean>

 

MyJobListener implements org.quartz.JobListener. Anything that you would like to run before the application call to the jobClass should be called with in this class. 

    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {

            JobDetail jobDetail = jobExecutionContext.getJobDetail();

            MyJobDetail myJobDetail = (MyJobDetail) jobDetail;          

            jobDetail.getJobDataMap().put("MessageAdded", myJobDetail.getMyMessage());

    }

 

In the preceding example, it is trying to copy the ‘myMessage’ value to the JobDataMap. (The logic is just for demonstration purpose)

 

The trigger declaration requires the reference to JobDetail, cronExpression and etc.

<bean id="myJobCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">

    <property name="cronExpression" value="0 0/2 * * * ?"/>

    <property name="jobDetail" ref="myJob"/>

    <property name="jobName" value="my_job"/>

    <property name="name" value="my_job_trigger"/>

    <property name="beanName" value="my_job"/>

</bean>

 

Cron-Expressions are used to configure instances of CronTrigger. Cron-Expressions are strings that are actually made up of seven sub-expressions, that describe individual details of the schedule. These sub-expression are separated with white-space, and represent:

1.       Seconds

2.       Minutes

3.       Hours

4.       Day-of-Month

5.       Month

6.       Day-of-Week

7.       Year (optional field)

More details about cron-Expression could be found at http://www.opensymphony.com/quartz/wikidocs/TutorialLesson6.html

 

The final declaration will be SchedulerFactoryBean. As mentioned earlier, It allows registration of JobDetails, Calendars and Triggers, automatically starting the scheduler on initialization and shutting it down on destruction.

<bean id="schedulerFactoryBean"  

         class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">

    <property name="jobDetails">

        <list>

            <ref bean="myJob"/>

        </list>

    </property>

    <property name="jobListeners">

        <list>

            <ref bean="myJobListener"/>

        </list>

    </property>

    <property name="triggers">

        <list>

            <ref bean="myJobCronTrigger"/>

        </list>

    </property>

    <property name="applicationContextSchedulerContextKey" value="applicationContext"/>

    <property name="overwriteExistingJobs" value="true"/>

    <property name="autoStartup" value="true"/>

    <property name="quartzProperties">

        <props>

            <prop key="org.quartz.scheduler.instanceName">MyJobScheduler</prop>

            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>

            <!–thread pool–>

            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>

            <prop key="org.quartz.threadPool.threadCount">25</prop>

            <prop key="org.quartz.threadPool.threadPriority">5</prop>

            <!–job store–>

            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>

            <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>

        </props>

    </property>

</bean>

 

Run Scheduled jobs

In a standard alone application you can call the scheduler to run in your main class

Scheduler scheduler = (Scheduler) context.getBean(" schedulerFactoryBean");

scheduler.start();

 

For a web application, you don’t need to anything as Spring will pick up your configuration file during the initialisation and fire the scheduled jobs.

 

Reference:

http://www.javaranch.com/journal/200711/combining_spring_and_quartz.html

http://www.opensymphony.com/quartz/

http://static.springframework.org/spring/docs/1.2.x/reference/scheduling.html

http://static.springsource.org/spring/docs/3.0.0.M1/javadoc-api/

 

 

Advertisements
This entry was posted in Scheduled Application. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s