Java——Quartz作业任务调度框架(二)

上一篇中,拥有一个简单使用Quartz的例子;
这一篇,将包括对Quartz的一些详细使用。

JobDetail 类

JobDetail为Job实例提供了许多设置属性,
JobDetail重要属性:

设定任务类、Job名称、组名称 和JobDataMap:JobBulider.newJob(MyJob.class).withIdentity("job1","group1").usingJobData("message","信息值").build();
获取名称:       JobDetail.getKey().getName()             // job1
获取组的名称:JobDetail.getKey().getGroup()            // group1 , 默认DEFAULT
获取任务类:    JobDetail.getJobClass().getName()   // com.example.MyJob
获取JobDataMap:JobDetail.getJobDataMap()

JobDataMap类

  1. 在任务调度时,JobDataMap存储在JobExecutionContext中,可以获取。
  2. JobDataMap可以装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。
  3. JobDataMap实现了JDK的Map接口,并添加了方便的方法来获取基本数据类型。
.usingJobData("message","信息值")

JobExecutionContext类

当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法;Job通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

context.getJobDetail().getKey().getName()     // 获取Job名称
context.getJobDetail().getKey().getGroup()     // 获取Job组的名称
context.getJobDetail().getJobClass().getName()     // 获取Job任务类
context.getJobDetail().getJobDataMap()     // 获取JobDetail中的JobDataMap
context.getJobDetail().getJobDataMap().getString("message")     //获取JobDetail中JobDataMap的message信息值
context.getTrigger().getKey().getName()     // 获取Trigger名称
context.getTrigger().getKey().getGroup()     // 获取Trigger组的名称
context.getTrigger().getJobDataMap()     //  获取Trigger中的JobDataMap
context.getFireTime()     //  获取当前任务执行时间
context.getNextFireTime()     //  获取下一次任务执行时间
context.getTrigger().getStartTime()     //  获取任务执行开始时间
context.getTrigger().getEndTime()     //  获取任务执行结束时间
context.getJobDetail().getJobDataMap().getString("message");
或
在MyJob类中添加message的属性以及setter方法,即可在直接通过message属性获取相应值(如果Trigger和JobDetail都设置了message属性,则以Trigger设置值为准)

有状态Job和无状态Job

默认为无状态Job。每次调用Job时都会创建一个新的JobDataMap对象,想要修改其中的键值对是没有效果的。
对MyJob类添加注解**@persistJobDataAfterExecution**成为有状态Job,多次调用Job期间可以持有一些状态信息,可实现count的累加计算。
修改状态信息:context.getJobDetail().getJobDataMap().put(“count”,count);

Trigger类

设置任务开始时间、结束时间:

Trigger trigger =TriggerBulider.newTrigger()
    .withIdentity("trigger1","group1")
    .startat(new Date())
    .endat(new Date())
    .withSchedule(
         SimpleScheduleBuilder.simpleSchedule()
         .repeatSecondlyForever(5)
         .withRepeatCount(3))
    .build();

获取任务开始时间、结束时间:

context.getTrigger().getStartTime()     //  获取任务执行开始时间
context.getTrigger().getEndTime()     //  获取任务执行结束时间

抽象触发器:
SimpleTrigger
CronTrigger
CalendarIntervalTrigger
DailyTimeIntervalTrigger

SimpleTrigger触发器
需在特定日期/时间启动,且以一个可能的间隔时间重复执行n次的Job设计的触发器。
可灵活设置开始时间/结束时间/重复次数/重复时间间隔。
CronTrigger触发器
需像日历那样按照日程类触发任务的触发器。
Cron表达式:cron表达式是一个由7个子表达式组成的字符串,这些子表达式用空格分隔,分别表示 秒、分钟、小时、月中天、月、周中天、年(可不填)。

SchedulerFactory类

一个Job 可以对应多个Trigger,但一个Trigger智能对应一个Job。
Scheduler的创建方式:
DirectSchedulerFactory
StdSchedulerFactory:
使用一组参数(java.util.Properties)来创建和初始化Quartz调度器;配置参数一般存储在quartz.properties文件中;调用getScheduler方法就能创建和初始化调度器对象。

得到SchedulerFactory实例:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
输出调度器开始时间,关联任务和触发器:
Date date =scheduler.scheduleJob(jobDetail,trigger);
启动任务调度:
scheduler.start();
挂起任务调度,暂停:
scheduler.standby();
重新启动任务调度:
scheduler.start();
重启后会连续执行挂起期间的调度任务。
关闭任务调度(true:等待所有正在执行的Job执行完毕后再关闭scheduler;false:直接关闭scheduler):
scheduler.stutdown(true);

quartz.properties文件

org.quartz.scheduler.instanceName = DefaultQuartzScheduler       // 调度器实例名
org.quartz.scheduler.instanceId = AUTO       //  调度器实例ID,必须唯一(集群时用到)
org.quartz.threadPool.threadCount = 10       // 处理Job的线程池个数
org.quartz.threadPool.threadPriority = 5       // 线程的优先级,1~10,默认5。
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool       // 指定的线程池
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore       // 作业存储设置
#org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin       // 插件
#org.quartz.plugin.jobInitializer.overWriteExistingJobs = true
#org.quartz.plugin.jobInitializer.failOnFileNotFound = true
#org.quartz.plugin.jobInitializer.validating = false

Quartz监听器

  1. Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种。
  2. 全局监听器、非全局监听器。全局监听器能够接收到所有的Job/Trigger的事件通知。非全局监听器智能在其上注册的Job/Trigger的事件。

JobListener:
任务调度过程中,与任务Job相关的事件包括:Job开始执行的提示,Job执行完成的提示等。

1. 接口JobListener实现:

public  class MyJobListener implements JobListener{
}

获取该JobListener的名称:

@override
public  String getName(){
    return this.getClass().getName();
}

Scheduler在JobDetail将要被执行时调用这个方法:

@override
public void jobToBeExecuted(JobExecutionContext context){
}

Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法:

@override
public void jobExecutionVetoed(JobExecutionContext context) {
}

Scheduler在JobDetail被执行之后调用这个方法:

@override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
}

2. 创建并注册一个JobListener
在scheduler.scheduleJob(jobDetail,trigger)后,scheduler.start()之前,
创建并注册一个全局的JobListener:

scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());

或创建并注册一个局部的JobListener:

 scheduler.getListenerManager().addJobListener(new MyJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1","group1")));

TriggerListener:
任务调度过程中,与触发器Trigger相关的事件包括:触发器触发、触发器未正常触发、触发器完成等。

1. 接口TriggerListener实现:

public class MyTriggerListener implements TriggerListener{

    private String name;
    
    public MyTriggerListener(String name) {
        this.name = name;
    }
    
    // 获取触发器名称
    @Override
    public String getName() {
         return this.getClass().getName();
         return name;
    }
    
    // 当与监听器相关联的Trigger被触发,Job上的execute()方法将被执行时,Scheduler就调用该方法。
    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext context) {
        String triggerName = trigger.getKey().getName();
        String info = triggerName + " was fired";
    }
    
    // 在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。
    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        String triggerName = trigger.getKey().getName();
        String info = triggerName + " was not vetoed";
        return false;    // true:表示不会执行Job方法
    }
    
    // Scheduler 调用这个方法是在 Trigger 错过触发时。你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。
    @Override
    public void triggerMisfired(Trigger trigger) {
        String triggerName = trigger.getKey().getName();
        String info = triggerName + " misfired";
    }
    
    //Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。
    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
        String triggerName = trigger.getKey().getName();
        String info = triggerName + " is complete";
    }

}

2. 创建并注册一个TriggerListener
在scheduler.scheduleJob(jobDetail,trigger)后,scheduler.start()之前,
创建并注册一个全局的TriggerListener:

scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListenerName"), EverythingMatcher.allTriggers());

或创建并注册一个局部的TriggerListener:

 scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListenerName"), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1","group1")));

SchedulerListener:
SchedulerListener会在Scheduler的生命周期中关键事件发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger,删除一个job/trigger,scheduler发生严重错误,关闭scheduler等。

1. 接口SchedulerListener 实现:

  1. jobScheduled方法:用于部署JobDetail时调用
  2. jobUnscheduled方法:用于卸载JobDetail时调用
  3. triggerFinalized方法:当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。
  4. triggersPaused方法:Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。
  5. triggersResumed方法:Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null。参数将为 null。
  6. jobsPaused方法:当一个或一组 JobDetail 暂停时调用这个方法。
  7. jobsResumed方法:当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。
  8. schedulerError方法:在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。
  9. schedulerStarted方法:当Scheduler 开启时,调用该方法
  10. schedulerInStandbyMode方法: 当Scheduler处于StandBy模式时,调用该方法
  11. schedulerShutdown方法:当Scheduler停止时,调用该方法
  12. schedulingDataCleared方法:当Scheduler中的数据被清除时,调用该方法。

2. 创建并注册一个SchedulerListener
在scheduler.scheduleJob(jobDetail,trigger)后,scheduler.start()之前,
创建并注册一个SchedulerListener :

scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());

移除对应的SchedulerListener :

// scheduler.getListenerManager().removeSchedulerListener(new MySchedulerListener());

欢迎指正,随时修改~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值