quartz使用记录

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任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值