quartz使用记录

来源:互联网 发布:知乎日报api接口 编辑:程序博客网 时间:2024/06/13 15:40

quartz简介

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.2.3。

quartz是一个任务调度系统,当应用程序需要天自动定时的完成一些任务的时候,quartz是首选,当然这些也可以使用timer(定时器)来实现。

quartz核心介绍

使用quartz的一些核心类的介绍:

  • Trigger:用来触发任务的触发器
  • Job:任务接口,需要执行的任务类实现这个接口的execute方法,Trigger按照指定的规则触发后会调用Job的execute方法
  • SimpleScheduleBuilder:创建普通的触发规则,例如每隔多少时间触发一次任务
  • CronScheduleBuilder:一般如果触发的规则比较复杂的话应该使用这个(注:这个类和上面的SimpleScheduleBuilder都是用来创建真正的规则的,他们并不是直接使用)
  • JobDetail:上面的Job类将被它使用
  • Scheduler:任务调度器,将Trigger和JobDetail绑定,调用Scheduler.start()方法之后,就会按照Trigger定义的规则触发Job了
  • SchedulerFactory:工厂类,使用它的getScheduler()方法可以得到Scheduler对象

使用的CronScheduleBuidler的时间配置链接:

http://blog.csdn.net/a355586533/article/details/40348537

使用quartz的一些例子

下面我附上一篇官方demo里面的例子

package org.quartz.examples.example12;//注意import static org.quartz.CronScheduleBuilder.cronSchedule;import static org.quartz.JobBuilder.newJob;import static org.quartz.TriggerBuilder.newTrigger;import org.quartz.JobDataMap;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerFactory;import org.quartz.Trigger;import org.quartz.impl.StdSchedulerFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * This example is a client program that will remotely  * talk to the scheduler to schedule a job.   In this  * example, we will need to use the JDBC Job Store.  The  * client will connect to the JDBC Job Store remotely to  * schedule the job. *  * @author James House, Bill Kratzer */public class RemoteClientExample {    public void run() throws Exception {        Logger log = LoggerFactory.getLogger(RemoteClientExample.class);        // First we must get a reference to a scheduler        SchedulerFactory sf = new StdSchedulerFactory();        Scheduler sched = sf.getScheduler();        // define the job and ask it to run        JobDetail job = newJob(SimpleJob.class)            .withIdentity("remotelyAddedJob", "default")            .build();        JobDataMap map = job.getJobDataMap();        map.put("msg", "Your remotely added job has executed!");        Trigger trigger = newTrigger()            .withIdentity("remotelyAddedTrigger", "default")            .forJob(job.getKey())            .withSchedule(cronSchedule("/5 * * ? * *"))            .build();        // schedule the job        sched.scheduleJob(job, trigger);        log.info("Remote job scheduled.");    }    public static void main(String[] args) throws Exception {        RemoteClientExample example = new RemoteClientExample();        example.run();    }}

注:上面的例子有一个大坑,上面的导包语句使用静态导包,即:import static,如:

import static org.quartz.CronScheduleBuilder.cronSchedule;import static org.quartz.JobBuilder.newJob;import static org.quartz.TriggerBuilder.newTrigger;

上面是静态导包语句,所在代码里面可以直接使用TriggerBuilder的newTrigger()静态方法,如果没有静态导包的话,那么直接复制官方demo的例子将报错
下面是SimpleJob类:

package org.quartz.examples.example12;import java.util.Date;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.JobKey;/** * <p> * A dumb implementation of Job, for unittesting purposes. * </p> *  * @author James House */public class SimpleJob implements Job {    public static final String MESSAGE = "msg";    private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);    /**     * Quartz requires a public empty constructor so that the     * scheduler can instantiate the class whenever it needs.     */    public SimpleJob() {    }    /**     * <p>     * Called by the <code>{@link org.quartz.Scheduler}</code> when a     * <code>{@link org.quartz.Trigger}</code> fires that is associated with     * the <code>Job</code>.     * </p>     *      * @throws JobExecutionException     *             if there is an exception while executing the job.     */    public void execute(JobExecutionContext context)        throws JobExecutionException {        // This job simply prints out its job name and the        // date and time that it is running        JobKey jobKey = context.getJobDetail().getKey();        String message = (String) context.getJobDetail().getJobDataMap().get(MESSAGE);        _log.info("SimpleJob: " + jobKey + " executing at " + new Date());        _log.info("SimpleJob: msg: " + message);    }}

javaweb项目中使用quartz的例子

InitializerQuartzServlet类:

public class InitializerQuartzServlet extends HttpServlet{        private StdSchedulerFactory schedFact = null;        private Scheduler scheduler = null;        @Override          public void init(ServletConfig cfg) throws javax.servlet.ServletException {              super.init(cfg);              try {                schedFact = new StdSchedulerFactory();                scheduler = schedFact.getScheduler();                JobDetail jobDetail = JobBuilder.newJob(GenerateDailyDataJob.class).withIdentity("dailyDataJob").build();                .repeatForever()).startNow().build();                Trigger trigger = TriggerBuilder.newTrigger()                        .withIdentity(TriggerKey.triggerKey("dailyTrigger", "dailyTriggerGroup"))                        .withSchedule(CronScheduleBuilder.cronSchedule("0 0 11 * * ?")).build();                scheduler.scheduleJob(jobDetail, trigger);                scheduler.start();            } catch (SchedulerException e) {                e.printStackTrace();            }        }          @Override          public void destroy() {              try {                //                scheduler.shutdown();            } catch (SchedulerException e) {                e.printStackTrace();            }        }  }

GenerateDailyDataJob类:

public class GenerateDailyDataJob implements Job{    @Override    public void execute(JobExecutionContext arg0) throws JobExecutionException {        System.out.println("hello, world!");    }}

因为实在web项目中使用,而且是每天上午11点就触发这个任务,所以需要将InitializerQuartzServlet 这个Servlet跟随容器一起启动,所以在web.xml中要配置:

  <servlet>        <servlet-name>InitializerQuartzServlet</servlet-name>        <servlet-class>            com.weixin.util.InitializerQuartzServlet        </servlet-class>        <init-param>            <param-name>shutdown-on-unload</param-name>            <param-value>true</param-value>        </init-param>        <!-- 加载及启动定时任务 true -->        <init-param>            <param-name>start-scheduler-on-load</param-name>            <param-value>true</param-value>        </init-param>        <!-- 启动延迟时间 60秒 -->        <init-param>            <param-name>start-delay-seconds</param-name>            <param-value>60</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>  

quartz使用中的问题

某次在使用quartz的时候,会触发多次job,也就是本来应该只执行一次job的时候执行了多次,后来在网上看到,quartz不会跟随着tomcat关闭而关闭,最后导致的结果是启动了多少次就开启了多少个quartz任务(很有可能是我没调用Scheduler.shutdown()方法),现在我在InitializerQuartzServlet 的destroy声明周期中调用了Scheduler.shutdown()方法,旨在tomcat容器关闭之后会关闭掉Job任务

0 0
原创粉丝点击