quartz的学习和简单使用

以前在框架中使用过,很多都是纯粹的复制粘贴,了解过用法知道如何配置,但时间久了就没什么印象了,现在重新捡起来,再次进行学习。

quartz相关的介绍都已经很多了,我就不重复啰嗦,简单说一下个人的认识和使用。

* 定时任务 quartz的设计比较合理,将调度Scheduler、触发Trigger、任务进行分离Job(这里使用JobDetail创建Job的实例)
* 调度Scheduler负责任务的调度执行以及任务的销毁
* 触发器设定Trigger事件的触发条件或时间,分为SimpleTrigger和CronTrigger两种常用模式,
* 当然还有其他两种模式CalendarIntervalTrigger 按日期触发的Trigger 和 DailyTimeIntervalTrigger 按天触发的Trigger
* 其中CronTrigger中的设置规范基本等同于cron4j,不过增加了秒
* JobDetail是任务的定义,而Job是任务的执行逻辑

在学习cron4j的时候,我使用了的内部类,在创建quartz的时候我也同样使用了内部类,但示例始终不能启动,找了很长时间,没想到这里还有个坑,现在也不知道因为什么。

下面代码是个反面教材,是不能运行的,需要将HelloTask类单独出来写才可以运行。

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.DateBuilder.evenMinuteDate ;  

/**
 * 
 * @author Uboobo
 * 
 * 定时任务 quartz的设计比较合理,将调度Scheduler、触发Trigger、任务进行分离Job(这里使用JobDetail创建Job的实例)
 * 调度Scheduler负责任务的调度执行以及任务的销毁
 * 触发器设定Trigger事件的触发条件或时间,分为SimpleTrigger和CronTrigger两种常用模式,
 * 当然还有其他两种模式CalendarIntervalTrigger 按日期触发的Trigger 和 DailyTimeIntervalTrigger 按天触发的Trigger
 * 其中CronTrigger中的设置规范基本等同于cron4j,增加了秒
 * JobDetail是任务的定义,而Job是任务的执行逻辑
 *
 */

public class QuartzTask
{
    // 创建scheduler
    public static void createScheduler(JobDetail job, Trigger trigger)
    {
    try
    {
        // 创建scheduler,需要捕获调度异常
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // 加入这个调度
        scheduler.scheduleJob(job, trigger);

        // 启动之
        scheduler.start();

        // 运行一段时间后关闭
        Thread.sleep(10000);

        scheduler.shutdown(true);

    } catch (SchedulerException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }

    // 创建Trigger
    public static Trigger createTrigger()
    {
    Trigger trigger = newTrigger()
        .withIdentity("myTrigger", "group1")
        .startNow()
        .withSchedule(simpleSchedule()
            .withIntervalInSeconds(10)//间隔时间是10s
            .repeatForever())
        .build();

    return trigger;
    }

    // 创建Job
    public static JobDetail createJob()
    {
    JobDetail job = newJob(HelloTask.class)
        .withIdentity("myJob", "group1")
        .build();
    return job;
    }

    // 内部类 ,坑在这这里,需要使用单独的类
    static class HelloTask implements Job
    {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        JobDetail detail = context.getJobDetail();
        // TODO Auto-generated method stub
        String name = detail.getJobDataMap().getString("name");

        System.out.println(" my job do..." + name);
    }

    }
    public static void main(String[] args) throws Exception {  
      
    JobDetail job = createJob();
    Trigger trigger = createTrigger();
    createScheduler(job,trigger);
      
    } 

代码里没有标注太多注释,这里多说几句,一个quartz任务要执行的话,首先要通过StdSchedulerFactory.getDefaultScheduler() 创建scheduler,只有这样才能使用调度,然后要通过Trigger去创建一个或多个触发器并设定执行时间,然后再去使用JobDetail创建job,再使用job去加载我们要去执行的类,最后使用调度去加载执行。

quartz的设计将其进行分层还是有很多好处,但也增加了一些复杂度,如果直接使用scheduler去调用job也是可以的,但如果实现多重负责设置就比较困难了。

下面贴一下可以运行的代码

    public static void main(String [] args)
    {
    try
    {
        // 创建scheduler
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // 定义一个Trigger
        Trigger trigger = newTrigger().withIdentity("trigger1", "group1") // 定义name/group
            .startNow()// 一旦加入scheduler,立即生效
            .withSchedule(simpleSchedule() // 使用SimpleTrigger
                    .withIntervalInSeconds(1) // 每隔一秒执行一次
                    .repeatForever()) // 一直执行,奔腾到老不停歇
            .build();

        // 定义一个JobDetail
        JobDetail job = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在
            .withIdentity("job1", "group1") // 定义name/group
            .usingJobData("name", "quartz") // 定义属性
            .build();

        // 加入这个调度
        scheduler.scheduleJob(job, trigger);

        // 启动之
        scheduler.start();

        // 运行一段时间后关闭
        Thread.sleep(100000);
        scheduler.shutdown(true);
        
    } catch (Exception e)
    {
        e.printStackTrace();
    }
    }
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/** 
 * hello world Quartz 
 * @author weeks 
 * 
 */
public class HelloJob implements Job
{

    private static Logger _log = LoggerFactory.getLogger(HelloJob.class);

    /** 
     * Job,Job需要一个公有的构造函数,否则Factory无法构建 
     */
    public HelloJob()
    {
    }

    /** 
     * 实现execute方法 
     */
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
    System.out.println(" my job do...");
    }
}

这里还遗留一个问题,import中使用了 static 有点不太明白,设计者为什么要这么做,这么做有什么好处,待我了解之后再来补充。

扫描二维码关注公众号,回复: 4869726 查看本文章

猜你喜欢

转载自www.cnblogs.com/shej123/p/10254301.html