Quartz任务调度框架 -- 三大API

一. 三大API – Job

1. JobDetail & Job & JobDataMap

JobDetail是任务的定义,而Job是任务的执行逻辑。在JobDetail里会引用一个Job Class定义。

每一个JobDetail都会有一个JobDataMap。JobDataMap本质就是一个Map的扩展类,只是提供了一些更便捷的方法,比如getString()之类的。

(1)直接获取JobDetail和JobDataMap
1. 修改HelloJob,获取JobDetail和JobDataMap的信息
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;

public class HelloJob implements Job {

  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    //1. 日期格式化
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String date = sdf.format(new Date());
    //2. 输出时间和"Hello World"字符串
    System.out.println(date + " : Hello World");
    //3. 获取jobDetail
    JobKey key = jobExecutionContext.getJobDetail().getKey();
    System.out.println("jobDetail 的name : "+key.getName());     //打印jobDetail 的name
    System.out.println("jobDetail 的group : "+key.getGroup());    //打印jobDetail 的group
    //4. 获取jobDataMap
    JobDataMap jobDetailDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
    String message = jobDetailDataMap.getString("message"); //
    float floatJobValue = jobDetailDataMap.getFloat("FloatJobValue");
    System.out.println("jobDataMap定义的message的值 : "+message );  //打印jobDataMap定义的message的值
    System.out.println("jobDataMap定义的floatJobValue的值 : "+floatJobValue );   //jobDataMap定义的floatJobValue的值
  }
}
2. 修改HelloScheduler

在HelloScheduler中设置jobDetail和trigger的group,并且在jobDetail中设置jobDataMap的Map值。

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class HelloScheduler {

  public static void main(String[] args) throws SchedulerException {
    //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
    JobDetail jobDetail = JobBuilder
        .newJob(HelloJob.class) //定义Job类为HelloJob类,真正的执行逻辑所在
        .withIdentity("myJob", "group1") //定义name 和 group
        .usingJobData("message","hello myJob1") //加入属性到jobDataMap
        .usingJobData("FloatJobValue",8.88f) //加入属性到jobDataMap
        .build();
    //2. 创建一个scheduleBuilder, 设置每5秒执行一次,一直执行
    SimpleScheduleBuilder schedule = SimpleScheduleBuilder.simpleSchedule()
        .withIntervalInSeconds(5)
        .repeatForever();
    //3. 创建一个Trigger触发器的实例
    SimpleTrigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("helloTrigger", "group1")
        .startNow()
        .withSchedule(schedule)
        .build();
    //4. 创建schedule实例
    StdSchedulerFactory ssf = new StdSchedulerFactory();
    Scheduler scheduler = ssf.getScheduler();
    scheduler.scheduleJob(jobDetail, trigger);
    scheduler.start();
  }
}
3. 执行main方法

执行结果:
在这里插入图片描述

(2)通过get、Set方式获取JobDetail和JobDataMap
1. 修改HelloJob
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;

public class HelloJob implements Job {

  //这里是第二种获取jobDataMap中的值的方法
  private String message;
  private Float floatJobValue;
  private Double doubleTriggerValue;

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public Float getFloatJobValue() {
    return floatJobValue;
  }

  public void setFloatJobValue(Float floatJobValue) {
    this.floatJobValue = floatJobValue;
  }

  public Double getDoubleTriggerValue() {
    return doubleTriggerValue;
  }

  public void setDoubleTriggerValue(Double doubleTriggerValue) {
    this.doubleTriggerValue = doubleTriggerValue;
  }

  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    //1. 日期格式化
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String date = sdf.format(new Date());
    //2. 输出时间和"Hello World"字符串
    System.out.println(date + " : Hello World");
    //3. 获取jobDetail
    JobKey key = jobExecutionContext.getJobDetail().getKey();
    System.out.println("jobDetail 的name : "+key.getName());     //打印jobDetail 的name
    System.out.println("jobDetail 的group : "+key.getGroup());    //打印jobDetail 的group
    //4. 获取jobDataMap
    System.out.println("jobDataMap定义的message的值 : "+message );  //打印jobDataMap定义的message的值
    System.out.println("jobDataMap定义的floatJobValue的值 : "+floatJobValue );   //jobDataMap定义的floatJobValue的值
  }
}
2. 执行main方法

在这里插入图片描述

二. 三大API – Tigger

(1)startTime和endTime

我们如果需要将定时任务设定一个开始和结束时间,就要使用Trigger的startTime和endTime了。

1. 编写TriggerScheduler01.java
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class TriggerSchedule01 {

  public static void main(String[] args) throws SchedulerException {
    //1. 创建一个jobDetail实例, 并与HelloJob绑定
    JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("seJob").build();
    //2. 设置开始时间和结束事件
    Date startDate = new Date();
    startDate.setTime(startDate.getTime() + 3000);
    Date endDate = new Date();
    endDate.setTime(endDate.getTime() + 15000);
    //3. 创建一个新的trigger设置为3秒后开始, 15秒后结束。
    SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("seTrigger")
        .startAt(startDate).endAt(endDate)
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatForever().withIntervalInSeconds(2))
        .build();
    //4. 创建Schedule实例
    StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
    Scheduler scheduler = stdSchedulerFactory.getScheduler();
    scheduler.start();
    scheduler.scheduleJob(jobDetail, trigger);
  }
}
2.编写 HelloJob.java
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Trigger;

public class HelloJob implements Job {
  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    //1. 日期格式化
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String date = sdf.format(new Date());
    //2. 输出时间和"Hello World"字符串
    System.out.println(date + " : Hello World");

    Trigger trigger = jobExecutionContext.getTrigger();
    System.out.println("事件开始时间:" + trigger.getStartTime());
    System.out.println("事件结束事件:" + trigger.getEndTime());
  }
}
3.执行结果

在这里插入图片描述

(2)BaseCalndar

此calendar不是java.util.Calendar,calendar是为了补充Trigger的时间,可以拍除了或加入一下特定的时间。Quartz 的 Calender 专门用于屏闭一个时间区间,使 Trigger 在这个区间中不被触发。

1. Quartz 包含了你的应用可用的许多的 Calender 类型

在这里插入图片描述

  • AnnualCalendar:排除每一年中指定的一天或者多少天 ,精度是天
  • CronCalendar:使用表达式排除某些时间段不执行,精度取决于Cron表达式,最大精度到秒
  • DailyCalendar:指定的时间范围内的每一天不执行,指定每天的时间段,格式是HH:MM[:SS[:mmm]]。也就是最大精度可以到毫秒。
  • HolidayCalendar:排除节假日,精度到天
  • MonthlyCalendar:排除月份中的数天,可选值为1-31。精度是天
  • WeeklyCalendar:排除星期中的一天或多天,可选值比如为java.util.Calendar.SUNDAY,精度是天。
    下面以AnnualCalendar举例,来实现某一天不执行程序。
2. 代码实现
2.1 编写Scheduler类CalendarSchedule.java
public class CalendarSchedule {
    public static void main(String[] args) throws SchedulerException {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //创建一个JobDetail的实例,将该实例与HelloJob绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("zhlJob").build();
        AnnualCalendar holidays = new AnnualCalendar();
        GregorianCalendar nationalDay = new GregorianCalendar(2017, 10, 27);  // 排除今天的时间2017年11月27日(月份是从0~11的)
        
        holidays.setDayExcluded(nationalDay,true); //排除的日期,如果为false则为包含*/
        //创建Scheduler实例
        StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = stdSchedulerFactory.getScheduler();
        //向Scheduler注册日历
        scheduler.addCalendar("holidays",holidays,false,false);
        Trigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity("zhlTrigger")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever()) //每一秒执行一次job
                .modifiedByCalendar("holidays")   //将我们设置好的Calander与trigger绑定
                .build();
        //让trigger应用指定的日历规则
        //scheduler.scheduleJob(jobDetail,simpleTrigger);
        System.out.println("现在的时间 :"+sf.format(new Date()));
        System.out.println("最近的一次执行时间 :"+sf.format(scheduler.scheduleJob(jobDetail,simpleTrigger))); //scheduler与jobDetail、trigger绑定,并打印出最近一次执行的事件
        scheduler.start();
    }
}
2.2 编写job类 ,仍然使用HelloJob就可以
public class HelloJob implements Job{public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //打印当前的执行时间 例如 2017-11-22 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("现在的时间是:"+ sf.format(date));
        //具体的业务逻辑
        System.out.println("具体执行的业务...");
        Trigger trigger = jobExecutionContext.getTrigger();
        System.out.println("开始的时间: "+sf.format(trigger.getStartTime())); //打印开始时间
        System.out.println("结束的事件: "+sf.format(trigger.getEndTime())); //打印结束时间
}
3.执行结果

在这里插入图片描述

(3)Trigger的实现类

在这里插入图片描述
SimpleTrigger和CronTrigger之前已经介绍过了,接下来介绍一下CalendarIntervalTrigger 和 DailyTimeIntervalTrigger

1. CalendarIntervalTrigger

CalendarIntervalTrigger:是一个具体的Trigger,用来触发基于定时重复的JobDetail。

Trigger将会每隔N个calendar在trigger中定义的时间单元触发一次。这个trigger不适合使用SimpleTrigger完成(例如由于每一个月的时间不是固定的描述),也不适用于CronTrigger(例如每5个月)。

相较于SimpleTrigger有两个优势:1、更方便,比如每隔1小时执行,你不用自己去计算1小时等于多少毫秒。 2、支持不是固定长度的间隔,比如间隔为月和年。但劣势是精度只能到秒。

它适合的任务类似于:9:00 开始执行,并且以后每周 9:00 执行一次

它的属性有:

  • interval 执行间隔 i
  • ntervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期)
    例子:
CalendarIntervalScheduleBuilder
     .calendarIntervalSchedule()
     .withIntervalInDays(1)  //每天执行一次
   //.withIntervalInHours(1)
   //.withIntervalInMinutes(1)
   //.withIntervalInMonths(1)
   //.withIntervalInSeconds(1)
   //.withIntervalInWeeks(1)
   //.withIntervalInHours(1)
     .build()
2. DailyTimeIntervalTrigger

指定每天的某个时间段内,以一定的时间间隔执行任务。并且它可以支持指定星期。

它适合的任务类似于:指定每天9:00 至 18:00 ,每隔70秒执行一次,并且只要周一至周五执行。

它的属性有:

  • startTimeOfDay 每天开始时间
  • endTimeOfDay 每天结束时间
  • daysOfWeek 需要执行的星期
  • interval 执行间隔
  • intervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期)
  • repeatCount 重复次数
2.1 编写Scheduler类
 public static void main(String[] args) throws SchedulerException {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder
                .newJob(HelloJob.class)
                .withIdentity("myJob", "group1") //定义name 和 group
                .build();

        //2.创建一个Trigger触发器的实例
        Trigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity("zhlTrigger")
                .withSchedule(
                        DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule()
                                .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(8, 0)) //每天8:00开始
                                .endingDailyAt(TimeOfDay.hourAndMinuteOfDay(17, 0)) //17:00 结束
                                .onDaysOfTheWeek(MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY) //周一至周五执行
                                .withIntervalInHours(1) //每间隔1小时执行一次
                                .withRepeatCount(100) //最多重复100次(实际执行100+1次)
                )
                .modifiedByCalendar("holidays")   //将我们设置好的Calander与trigger绑定
                .build();

        //3.创建schedule实例
        StdSchedulerFactory factory = new StdSchedulerFactory();
        Scheduler scheduler = factory.getScheduler();
        System.out.println("现在的时间 :"+sf.format(new Date()));
        System.out.println();
        System.out.println("最近的一次执行时间 :"+sf.format(scheduler.scheduleJob(jobDetail,simpleTrigger))); //scheduler与jobDetail、trigger绑定,并打印出最近一次执行的事件
        scheduler.start();
    }
2.2 打印的效果

在这里插入图片描述
转自:https://www.cnblogs.com/zhanghaoliang/p/7886110.html

猜你喜欢

转载自blog.csdn.net/qq_36662478/article/details/88667617