开发者

How to use Quartz with QuartzInitializerListener?

I'm having trouble to understand how to use Quartz with QuartzInitializerListener.

First I declare that listener in deployment descriptor. But then, how to I add my jobs? Taking a look at QuartzInitializerListener implementation, I see it creates the SchedulerFactory and Scheduler, but I don't see any way to add jobs. The factory receives a configuration fil开发者_JS百科e, but again there's nothing related to the jobs there.

I only found very simples examples from my searches, all about instantiating everything in main method.

Can anyone point me to a more real example? I'm using JBoss 5 if that matters. Thanks.


Hi Here is the answer to your query:

1) Step 1: Write Job:

package com.hitesh.quartz.test;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class QuartzJob implements Job {

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("Hello");

    }

}

2) Write web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>TestWebBasedQuartz</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <context-param>
        <param-name>quartz:shutdown-on-unload</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>quartz:wait-on-shutdown</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>quartz:start-on-load</param-name>
        <param-value>true</param-value>
    </context-param>

    <listener>
        <listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class>
    </listener>

    <listener>
        <listener-class>com.hitesh.quartz.test.QuartzJobListener</listener-class>
    </listener>
</web-app>

As you can see there are two listeners. One belongs to Quartz API and other to your API. First Quartz API listener will execute as it comes first in order. At this moment we will have ready made scheduler factory. This listener will start scheduler also if corresponding property "quartz:start-on-load" is either not specified or specified as true.

3) Write your Quartz Listener :

package com.hitesh.quartz.test;


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzJobListener implements ServletContextListener {

    private Scheduler scheduler;
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {

    }

    @Override
    public void contextInitialized(ServletContextEvent ctx) {
        JobDetail job = JobBuilder.newJob(QuartzJob.class)
        .withIdentity("dummyJobName", "group1").build();

        Trigger trigger = TriggerBuilder
        .newTrigger()
        .withIdentity("dummyTriggerName", "group1")
        .withSchedule(
            SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(1).repeatForever())
        .build();
        try{
            scheduler = ((StdSchedulerFactory) ctx.getServletContext().getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY)).getScheduler();
            scheduler.scheduleJob(job, trigger);    
        }catch(SchedulerException e){

        }


    }



}

This listener will execute after Quartz listener has executed. This means we have ready made Scheduler Factory with us and a started scheduler. So you only need to add job to scheduler. As you can see the contextDestroyed method is empty as scheduler shutdown work will be carried out by Quartz API schedluer.


Everything is described in the source code Javadoc you quote:

A StdSchedulerFactory instance is stored into the ServletContext. You can gain access to the factory from a ServletContext instance like this:

StdSchedulerFactory factory = (StdSchedulerFactory) ctx
       .getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);

EDIT: This means that when you are using this listener you can obtain SchedulerFactory inside every servlet/Spring MVC controller/... by running:

StdSchedulerFactory factory = (StdSchedulerFactory)httpServletRequest
    .getServletContext()
    .getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);

Note that context listeners are guaranteed to be executed before any servlet is used to handle incoming requests. This means that the scheduler will always be properly initialized prior to its usage.


Summary of the discussion in the comments below, the discussion actually answers the question being asked: If you want to add jobs at application startup, write another listener (similar to the one provided by Quartz), lookup StdSchedulerFactory (ServletContext is easily available) and do what you want. The listeners are guaranteed to execute in the same order as they are declared in web.xml, so put your listener after Quartz one.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜