java 如何在 QuartzInitializerListener 中使用 Quartz?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5663640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:10:16  来源:igfitidea点击:

How to use Quartz with QuartzInitializerListener?

javaquartz-scheduler

提问by A. Kronen

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

我无法理解如何将 Quartz 与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 SchedulerFactoryand Scheduler, but I don't see any way to add jobs. The factory receives a configuration file, but again there's nothing related to the jobs there.

首先,我在部署描述符中声明该侦听器。但是,我如何添加我的工作?看一下QuartzInitializerListener implementation,我看到它创建了SchedulerFactoryand Scheduler,但我没有看到任何添加作业的方法。工厂收到一个配置文件,但同样没有与那里的工作相关的任何内容。

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

我只从我的搜索中找到了非常简单的例子,都是关于在 main 方法中实例化所有东西。

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

谁能指出一个更真实的例子?如果这很重要,我正在使用 JBoss 5。谢谢。

采纳答案by Tomasz Nurkiewicz

Everything is described in the source codeJavadoc you quote:

您引用的源代码Javadoc 中描述了所有内容:

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

StdSchedulerFactory 实例存储在 ServletContext 中。您可以像这样从 ServletContext 实例访问工厂:

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

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

编辑:这意味着当您使用此侦听器时,您可以SchedulerFactory通过运行在每个 servlet/Spring MVC 控制器/...中获取:

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.

请注意,保证在使用任何 servlet 处理传入请求之前执行上下文侦听器。这意味着调度程序将始终在使用之前正确初始化。


Summary of the discussion in the comments below, the discussion actuallyanswers 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.


下面评论中的讨论总结,讨论实际上回答了被问到的问题:如果您想在应用程序启动时添加作业,请编写另一个侦听器(类似于 Quartz 提供的那个),查找 StdSchedulerFactory(ServletContext 很容易获得)和做你想做的。监听器保证按照它们在 web.xml 中声明的顺序执行,所以把你的监听器放在 Quartz 之后。

回答by Hitesh

Hi Here is the answer to your query:

您好以下是您的问题的答案:

1) Step 1: Write Job:

1) 第一步:写作业:

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:

2)编写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.

如您所见,有两个侦听器。一个属于 Quartz API,另一个属于您的 API。第一个 Quartz API 侦听器将按顺序执行。此刻我们将有现成的调度器工厂。如果相应的属性 "quartz:start-on-load" 未指定或指定为 true,此侦听器也将启动调度程序。

3) Write your Quartz Listener :

3) 编写你的 Quartz 监听器:

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.

这个侦听器将在 Quartz 侦听器执行后执行。这意味着我们已经准备好了调度器工厂和一个启动的调度器。所以你只需要将作业添加到调度程序。如您所见,contextDestroyed 方法是空的,因为调度程序关闭工作将由 Quartz API schedluer 执行。