• Quartz任务调度


    Java定时任务

    数据结构–堆

    堆是一种特殊的树,只要满足下面两个条件,它就是一个堆:

    (1)堆是一颗完全二叉树(除最后一层以外,剩下的层达到最大节点)

    (2)堆种某个节点的值总是不大于(或不小于)其父节点的值

    其中,我们把根节点最大的堆叫做大顶堆,根节点最小的堆叫做小顶堆

    满二叉树:所有层都达到最大节点数 1、2、4、8

    在这里插入图片描述

    完成二叉树:除了最后一层外其他层都达到最大节点数,且最后一层节点都靠左排列(1、2、4、2)

    在这里插入图片描述

    完全二叉树最适合用数组做存储,因为它的节点都是紧凑的,且只有最后一层节点数不满

    在这里插入图片描述

    为什么下标0的位置不存在元素呢?

    这是因为这样存储我们可以很方便地找到父节点:下标/2,比如,4的节点即4/2=2,5的父节点即5/2=2。

    堆也是一颗完全二叉树,但是它的元素必须满足每个节点的值都不大于(或不小于)其父节点的值。比如下面的堆:

    在这里插入图片描述

    数组存储结构:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

    这时候我们要找8的父节点就拿8的位置下标 5/2=2,也就是5这个节点的位置。这也是为了我们后面堆化。

    插入元素

    规律:插入尾部,然后上浮

    往堆中插入一个元素后,我们需要继续满足堆的两个特性,即:

    (1)堆是 一颗完全二叉树

    (2)堆中某个节点的值总是不大于(或不小于)其父节点的值。

    为了满足条件(1),所以我们把元素插入到最后一层最后一个节点往后一位的位置,但是插入之后可能不再满足条件(2)了,所以这时我们需要堆化。

    比如,上面那个堆我们需要插入元素2,我们把它放在9后面,这时不满足条件(2)了,我们就需要堆化。(这是一个小顶堆)

    在这里插入图片描述

    在完全二叉树中,插入的节点与它的父节点相比,如果比父节点小,就交换它们的位置,再往上和父节点相比,如果还比父节点小,就再次交换位置,直到比父节点大为止。

    在数组中,插入的节点与n/2位置的节点相比,如果比n/2位置的节点小,就交换它们的位置,再往前与n/4位置的节点相比,如果比n/4位置的节点小,再次交换位置,直到比n/(2^x)位置的节点大为止。

    这就是插入元素时进行的堆化,也叫自下而上的堆化。

    从插入元素的过程中,我们知道每次与n/(2^x)的为止进行比较,所以,插入元素的时间复杂度为O(log n)。

    删除堆顶元素

    将尾部(最大的元素)元素放到堆顶,然后下沉

    小顶堆中堆顶存储的是最小的元素,这时候我们把它删除会怎样呢?

    删除了堆顶元素后,要使得还满足堆的两个特性,首先,我们可以把最后一个元素移到根节点的位置,这时候就会满足条件(1),之后就是使它满足条件(2),就需要堆化了。

    在这里插入图片描述

    在完全二叉树中,把最后一个节点放到堆顶,然后与左右子节点中最小的交换位置(因为是小堆顶),依次往下,直到其比左右子节点都小为止。

    在数组中,把最后一个元素移到下标为1的位置,然后与下标为2和3的位置对比,发现8比2大,且2是2和3之间最小的,所以与2交换位置,然后再与4和5的位置对比,发现8比5大,且5是5和7之间最小的,所以与5交换位置,没有左右子节点了,堆化结束。

    这就是删除元素时进行的堆化,也叫自上而下的堆化。

    从删除元素的过程,我们知道把最后一个元素拿到根节点后,每次与2n和(2n+1)位置的元素比较,取其小者,所以删除元素的时间复杂度也为O(log n)。

    Quartz任务调度

    一、Quartz概念

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目。

    Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。

    Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。

    Quartz 允许程序开发人员根据时间的间隔来调度作业。

    Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。

    核心概念

    我们需要明白 Quartz 的几个核心概念,这样理解起 Quartz 的原理就会变得简单了。

    1. Job

      表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:

      void execute(JobExecutionContext context) 
      
      • 1
    2. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。

    3. Trigger 代表一个调度参数的配置,什么时候去调。

    4. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

    二、Quartz运行环境

    • Quartz 可以运行嵌入在另一个独立式应用程序。
    • Quartz 可以在应用程序服务器(或 servlet 容器)内被实例化,并且参与 XA 事务。
    • Quartz 可以作为一个独立的程序运行(其自己的 Java 虚拟机内),可以通过 RMI 使用。
    • Quartz 可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行。

    三、Quartz设计模式

    • Builder模式
    • Factory模式
    • 组件模式
    • 链式编程

    四、Quartz学习的核心概念

    • 任务Job

      Job就是你想要实现的任务类,每一个Job必须实现org.quartz.Job接口,且只需要实现接口定义的execute()方法

    • 触发器Trigger

      Trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点会执行该任务。Trigger主要包含两种SimpleTrigger和CronTrigger两种。关于两者的区别的使用场景,将在下面讲解

    • 调度器Scheduler

      Scheduler为任务的调度器,它会将任务Job和触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job

    五、Quartz的体系结构

    在这里插入图片描述

    六、Quartz的几个常用API

    以下是Quartz编程API几个重要接口,也是Quartz的重要组件

    • Scheduler用于与调度程序交互的主程序接口。

      Scheduler调度程序(任务执行计划表),只有安排进执行计划的任务Job(通过scheduler.scheduleJob方法安排进执行计划),当它预先定义的执行时间到了的时候(任务触发Trigger),该任务才会执行

    • Job我们预先定义的希望在未来时间能被调度程序执行的任务类,我们可以自定义

    • JobDetail 使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建的

    • JobDataMap 可以包含不限量的(序列化)数据对象,在job实例执行的时候,可以使用其中的数据,JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法

    • Trigger 触发器,Trigger对象是用来触发执行任务Job的。当调度一个Job时,我们实例一个触发器然后调整它的属性来满足Job执行的条件。表明任务在什么时候会执行。定义了一个已经被安排的任务将会在什么时候执行的时间条件,比如每2秒执行一次

    • JobBUilder用于声明一个任务实例,也可以定义关于该任务的详情,比如任务名、组名等,这个声明的实例将会作为一个实际执行的任务。

    • TriggerBuilder 触发器创建器,用户创建触发器Trigger实例

    • JobListener、``TriggerListenerSchedulerListener`监听器,用于对组件的监听

    七、Quartz使用

    =注意:如果定时任务的开始时间小于当前时间,则定时任务立即执行=

    1.入门案例

    引入maven依赖

    
    
    <dependency>
        <groupId>org.quartz-schedulergroupId>
        <artifactId>quartzartifactId>
        <version>2.3.2version>
    dependency>
    
    
    
    <dependency>
        <groupId>org.quartz-schedulergroupId>
        <artifactId>quartz-jobsartifactId>
        <version>2.3.2version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    案例:

    开发任务类

    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    /**
    	@DisallowConcurrentExecution:将该注解加到job类上,告诉Quartz不要并发地执行同一个JobDetail实例
    */
    @PersistJobDataAfterExecution
    @DisallowConcurrentExecution 
    public class TaskJob implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            System.out.println("time = " + time);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试

    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class test {
    
        public static void main(String[] args) throws SchedulerException {
            //获取调度器
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    
            //获取任务实例
            JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
                    .withIdentity("job1", "group1")//参数1:任务名(唯一实例),参数2:组名
                    .build();
    
            //获取触发器
            SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "triggerGroup1")//参数1:任务名(唯一实例),参数2:组名
                    .startNow()//马上启动触发器
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever())
                    .build();
    
            //让调度器关联任务和触发器
            scheduler.scheduleJob(jobDetail,simpleTrigger);
    
            //启动
            scheduler.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    2.Job和JobDetail介绍
    • Job :工作任务调度的接口,任务类需要实现该接口。该接口中定义execute方法,类似JDK提供的TimeTask类的run方法。在里面编写任务执行的业务逻辑

    • Job实例在Quartz中的生命周期:每次调度器执行Job时,它在调用execute方法前会创建一个新的Job实例,当调用完毕后,关联的Job对象实例会被释放,释放的实例会被垃圾回收机制回收。

    • JobDetail :jobDetail为job实例提供了许多设置属性,以及jobDataMap成员变量属性,它用来存储特定job实例的状态信息,调度器需要借助jobDetail对象来添加job实例

    • JobDetail重要属性:name、group、jobClass、jobDataMap

      //获取任务名,必填
      String name = jobDetail.getKey().getName();
      //获取任务组名,注意:如果没有指定组名,默认为DEFAULT
      String groupName = jobDetail.getKey().getGroup();
      //获取任务类
      String className = jobDetail.getJobClass().getName();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    3.JobExecutionContext介绍
    • 当Scheduler调用一个Job,就会将jobExecutionContext传递给job的execute()方法
    • job能通过jobExecutionContext对象访问到Quartz运行时候的环境以及job本身的明细数据
    4.JobDataMap介绍

    1)使用Map获取

    • 在进行任务调度时,JobDataMap存储在jobExceutionContext中,非常方便获取
    • JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时,这些参数对象会传递给它
    • JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法用来存取基本数据类型

    存:

    位置:创建时一并加入

    JobDataMap jobDataMap = new JobDataMap();
    jobDataMap.put("message","任务的jobDataMap数据");
    
    //获取任务实例
    JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
        .withIdentity("job1", "group1")//参数1:任务名(唯一实例),参数2:组名
        .usingJobData(jobDataMap)
        .build();
    
    JobDataMap triggerByJobDataMap = new JobDataMap();
    jobDataMap.put("message","触发器的jobDataMap数据");
    //获取触发器
    SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
        .withIdentity("trigger1", "triggerGroup1")//参数1:任务名(唯一实例),参数2:组名
        .startNow()//马上启动触发器
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever())
        .usingJobData(triggerByJobDataMap)
        .build();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    取:

    位置:任务类中的execute方法中

    
    JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
    String message = jobDataMap.getString("message");
    
    JobDataMap triggerJobDataMap = jobExecutionContext.getTrigger().getJobDataMap();
    String triggerMessage = triggerJobDataMap.getString("message");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2)Job实现类中添加setter方法对应JobDataMap的键值,Quartz框架默认的JobFactory实现类在初始化job实例对象时会自动地调用这些setter方法,把key对应的值赋值给变量

    private String message;
    
    public void setMessage(String message){
        this.message = message;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:如果遇到同名的key,Trigger中的.usingJobDataMap()方法传入的map中的key所对应的值会覆盖jobDetail中的.usingJobDataMap()方法传入的map中的key对应的值(简单理解:如果Trigger和JobDetail的JobDataMap有相同key,使用成员变量获取值,会以Trigger优先)

    5.有状态的Job和无状态的Job

    @PersistJobDataAfterExecution注解的使用

    有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,而默认的无状态Job每次调用时都会创建一个新的JobDataMap。

    注解的作用就是 可以让在本次启动中 JobDataMap中的一些信息共享使用。例如:累加器等

    6.Trigger介绍

    在这里插入图片描述

    Quartz有一些不同的触发器类型,不过,用得最多的是SimpleTriggerCronTrigger

    (1)jobKey

    表示job实例的标识,触发器被触发时,该指定的job实例会被执行。

    Trigger trigger = jobExecutionContext.getTrigger();
    JobKey jobKey = trigger.getJobKey();
    String jobKeyName = jobKey.getName();
    String group = jobKey.getGroup();
    
    • 1
    • 2
    • 3
    • 4

    (2)startTime

    标识触发器的时间表,第一次开始被触发的时间,它的数据类型是java.util.Date。

    Trigger trigger = jobExecutionContext.getTrigger();
    Date startTime = trigger.getStartTime();
    
    • 1
    • 2

    (3)endTime

    指定触发器终止被触发的时间,它的数据类型是java.util.Date。

    Trigger trigger = jobExecutionContext.getTrigger();
    Date endTime = trigger.getEndTime();
    
    • 1
    • 2

    注意:如果是创建job实例时,使用了startNow()方法,立即执行,则无法获取开始时间和结束时间。如果需要获取两个变量值,则必须都设置,只设置其中一个获取时将会报错。

    7.SimpleTrigger触发器

    SimpleTrigger对于设置和使用是最为简单的一种QuartzTrigger。

    它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行n次的Job所设计的。

    案例:在指定的时间间隔内多次执行任务 任务:每5秒执行一次,且执行3次

    上重要代码:
    //获取触发器
    SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
        .withIdentity("trigger1", "triggerGroup1")//参数1:任务名(唯一实例),参数2:组名
        .startNow()//马上启动触发器
        //每5秒执行一次,且执行3次 扩展:withRepeatCount方法参数从0开始
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).withRepeatCount(2))
        .build();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意点:

    • SimpleTrigger的属性有:开始时间、结束时间、重复执行次数和重复执行的时间间隔
    • 重复执行次数的属性的值可以为0、正整数或常量(例如:SimpleTrigger.REPEAT_INDEFINITELY)
    • 重复执行的时间间隔属性值必须大于0或长整数的正整数,时间间隔有多个方法,常用有毫秒(withIntervalInMilliseconds)、秒(withIntervalInSeconds)、分(withIntervalInMinutes)、时(withIntervalInHours)为单位的时间间隔
    • 如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒触发一次直到指定的结束时间的Trigger,而无须去计算从开始到结束的所重复次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性值即可
    8.CronTrigger触发器

    基于日历的作业调度器,使用CronTrigger,你可以指定诸如“每个周五中午”,或者“每个工作日的9:30”,又或者“从每个周一、周三、周五的上午9:30到上午10:00之间每隔5分钟”这样日程安排来触发。甚至,像SimpleTrigger一样,CronTrigger也有一个startTime以指定日程从什么时间开始,也有一个(可选)endTime以指定何时日程不再继续.

    (1)Cron Expressions — Cron表达式

    Cron表达式被用来配置CronTrigger实例。Cron表达式是一个由7个子表达式组成的字符串,每个子表达式都描述了一个单独的日程细节。这些子表达式用空格分隔。

    详细介绍请看:https://blog.csdn.net/zhangruilinmoo/article/details/107205096

    9.配置资源SchedulerFactory

    Quartz以模块方式构架。所有的Scheduler实例由SchedulerFactory创建
    一个Job(任务)可以对应多个Trigger(触发器),而对于Trigger(触发器)而言,一个Tigger对应一个Job(任务)

    Scheduler的创建方式

    1)StdSchedulerFactory

    简介:Quartz默认的SchedulerFactory

    执行:

    • 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器

    • 配置参数一般存储在quartz.properties文件中

    • 调用getScheduler方法就能创建和初始化调度器对象

      • SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        
        • 1
        • 2

    用法一:输出调度器开始的时间(重要:使得任务和触发器进行关联)

    Date scheduleJob(JobDetail jobDetail,Trigger trigger)

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = scheduler.scheduleJob(job,trigger);
    System.out.println("调度器开始的时间 time=" + sdf.format(data));
    
    • 1
    • 2
    • 3

    用法二:启动任务调度

    void start();

    scheduler.start();
    
    • 1

    用法三:任务调度挂起,即暂停操作

    void standby();

    scheduler.standby();
    
    • 1

    用法四:关闭任务调度

    void shutdown()

    shutdown(true):表示等待所有正在执行的job执行完毕之后,再关闭Scheduler

    shutdown(false):表示直接关闭Scheduler

    2)DirectSchedulerFactory(了解)

    DirectSchedulerFactory是对SchedulerFactory的直接实现,通过它可以直接构建Scheduler,threadpool等

    DirectSchedulerFactory directSchedulerFactory = DirectSchedulerFactory.getInstance();
    Scheduler scheduler = directSchedulerFactory.getScheduler();
    
    • 1
    • 2
    10.Quartz.properties配置文件介绍

    在这里插入图片描述

    我们可以在项目的资源下添加quartz.properties文件,去覆盖底层的配置文件

    配置介绍

    • 调度器属性

    org.quartz.scheduler.instanceName属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名。

    org.quartz.scheduler.instanceId属性和前者一样,也允许任何字符串,但这个值必须在所有调度器实例中是唯一的,尤其是在一个集群环境中,作为集群的唯一key。假如想Quartz帮你生成这个值的话,可以设置为AUTO。

    • 线程池属性

    org.quartz.threadPool.threadCount:处理job的线程个数,至少为1,但最多的话不要超过100.在多数机器上设置该值超过100的话就会显得相当不实用了,特别是在job执行时间较长得情况下

    org.quartz.threadPool.threadPriority:线程得优先级。优先级别高的线程比级别低的线程优先得到执行。最少为1,最大为10,默认为5

    org.quartz.threadPool.class:一个实现了org.quartz.sql.ThreadPool接口的类,Quartz自带的线程池实现类是org.quartz.smpl.SimpleThreadPool

    备注:简单了解 ,如果需要深入了解,可以找度娘自行查询

    11.Quartz监听器
    a.概念

    Quartz的监听器用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知。类似于任务执行过程中的邮件、短信类的提醒。Quartz监听器主要有JobListenerTriggerListenerSchedulerListener三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,两者的区别在于:

    全局监听器能够接收到所有的Job/Triiger的事件通知,

    非全局监听器只能接收到在其上注册的job或trigger的事件,不在其上注册的job或trigger则不会进行监听。

    b.JobListener

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

    接口:

    package org.quartz;
    
    public interface JobListener {
        /*
        	用于获取该jobListener的名称
        */
        String getName();
    
        /*
        	Scheduler在JobDetail将要被执行时调用这个方法
        */
        void jobToBeExecuted(JobExecutionContext var1);
    
        /*
        	Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法
        */
        void jobExecutionVetoed(JobExecutionContext var1);
    
        /*
        	Scheduler在JobDetail被执行之后调用该方法
        */
        void jobWasExecuted(JobExecutionContext var1, JobExecutionException var2);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    使用步骤:

    • 实现JobListener接口,并按照自身需求实现对应的方法

    • 创建并注册监听器

      都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

      scheduler.scheduleJob(jobDetail,simpleTrigger);
      
      //全局监听器
      scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
      
      //局部监听器,指定jobKey(唯一标识)。在创建job任务类时,通过withIdentity方法添加
      scheduler.getListenerManager().addJobListener(new MyJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1", "group1")));
      
      scheduler.start();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    c.TriggerListener

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

    接口:

    package org.quartz;
    
    import org.quartz.Trigger.CompletedExecutionInstruction;
    
    public interface TriggerListener {
        /*
        	用于获取触发器的名称
        */
        String getName();
    
        /*
        	当与监听器相关的Trigger被触发,job上的execute方法将被执行时,Scheduler就调用该方法
        */
        void triggerFired(Trigger var1, JobExecutionContext var2);
    
        /*
        	在Trigger触发后,job将要被执行时由Scheduler调用这个方法。TriggerListener给了一个选择去否决job的执行,假如这个方法返回true,这个job将不会为此次Trigger触发而得到执行
        	trur:表示不会执行,false:表示执行
        */
        boolean vetoJobExecution(Trigger var1, JobExecutionContext var2);
    
        /*
        	在Trigger错过触发时由Scheduler执行
        */
        void triggerMisfired(Trigger var1);
    
        /*
        	Trigger被触发并且完成job的执行时,执行该方法
        */
        void triggerComplete(Trigger var1, JobExecutionContext var2, CompletedExecutionInstruction var3);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    使用步骤:

    • 实现TriggerListener接口,并按照自身需求实现对应的方法

    • 创建并注册监听器

      都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

      scheduler.scheduleJob(jobDetail,simpleTrigger);
      
      //全局监听器
      scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), EverythingMatcher.allTriggers());
      
      //局部监听器,指定TriggerKey(唯一标识)。在创建触发器时,通过withIdentity方法添加
      scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1", "triggerGroup1")));
      
      scheduler.start();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    d.SchedulerListener

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

    public interface SchedulerListener {
        //在调度JobDetail时调用
        void jobScheduled(Trigger var1);
    	//当JobDetail未被调度时调用
        void jobUnscheduled(TriggerKey var1);
    	//当触发器达到不再触发的条件时调用
        void triggerFinalized(Trigger var1);
    	//当一个Trigger被暂停时调用
        void triggerPaused(TriggerKey var1);
    	//当一组Trigger被暂停时调用
        void triggersPaused(String var1);
    	//当一个Trigger从暂停中恢复时调用
        void triggerResumed(TriggerKey var1);
    	//当一组Trigger从暂停中恢复时调用
        void triggersResumed(String var1);
    	//当添加了JobDetail时调用。
        void jobAdded(JobDetail var1);
    	//当JobDetail被删除时调用。
        void jobDeleted(JobKey var1);
    	//在JobDetail暂停时调用。
        void jobPaused(JobKey var1);
    	//在暂停一组JobDetail时调用
        void jobsPaused(String var1);
    	//当一个JobDetail从暂停中恢复时调用
        void jobResumed(JobKey var1);
    	//当一组JobDetail从暂停中恢复时调用
        void jobsResumed(String var1);
    	//当调度器内部发生严重错误时,由调度器调用——例如JobStore中的重复失败,或在触发器触发时无法实例化Job实例。
        void schedulerError(String var1, SchedulerException var2);
    	//由调度程序调用,以通知侦听器它已移动到待机模式。
        void schedulerInStandbyMode();
    	//当scheduler启动完成时调用
        void schedulerStarted();
    	//当scheduler启动中时调用
        void schedulerStarting();
    	//当scheduler停止时调用
        void schedulerShutdown();
    	//关闭序列时调用
        void schedulerShuttingdown();
    	//当scheduler中的数据被清除时调用
        void schedulingDataCleared();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    使用步骤:

    • 实现SchedulerListener接口,并按照自身需求实现对应的方法

    • 创建并注册监听器

      都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

      scheduler.scheduleJob(jobDetail,simpleTrigger);
      
      scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
      
      scheduler.start();
      
      • 1
      • 2
      • 3
      • 4
      • 5

    Job实例。
    void schedulerError(String var1, SchedulerException var2);
    //由调度程序调用,以通知侦听器它已移动到待机模式。
    void schedulerInStandbyMode();
    //当scheduler启动完成时调用
    void schedulerStarted();
    //当scheduler启动中时调用
    void schedulerStarting();
    //当scheduler停止时调用
    void schedulerShutdown();
    //关闭序列时调用
    void schedulerShuttingdown();
    //当scheduler中的数据被清除时调用
    void schedulingDataCleared();
    }

    
    使用步骤:
    
    - 实现`SchedulerListener`接口,并按照自身需求实现对应的方法
    
    - 创建并注册监听器
    
      都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发
    
      ```java
      scheduler.scheduleJob(jobDetail,simpleTrigger);
      
      scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
      
      scheduler.start();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    【云原生-白皮书】简章2:深入理解DevOps+微服务
    iPhone 12电池寿命结果:四款机型都进行了比较
    流量卡套餐解析:首月月租及套餐按天折算,这个你明白了吗?
    There are test failures.【非常详细,已解决】
    【物理应用】大气辐射和透射率模型及太阳和月亮模型(Matlab代码实现)
    自动化运维机器人(RPA)在银行IT运维领域应用场景分析
    one-hot和Embedding
    两栏布局:左侧固定,右侧自适应
    达梦类型转换问题-float转换为varchar
    信钰证券:积极因素不断积累 机构看多中长期市场
  • 原文地址:https://blog.csdn.net/zhangruilinmoo/article/details/126821117