1 SchedulerFactory

1.1 概述

  • Quartz是以模块的方式构建的,因为,要使它运行,几个组件必须很好的组合在一起。非常幸运的是,已经有了一些现存的助手可以完成这些工作。
  • 所有Scheduler实例都是由SchedulerFactory创建的。
  • Quartz的三个核心概念:调度器(Scheduler)、任务(Job)和触发器(Trigger),三者之间的关系是:

  • 一个作业,比较重要的的三个要素就是Scheduler、JobDetail和Trigger。而Trigger对于Job而言就好比是一个驱动器;没有触发器来定时驱动作业,作业就无法运行;对于Job而言,一个Job可以对应多个Trigger,但是对于Trigger而言,一个Trigger只能对应一个Job;所以一个Trigger只能被指派给一个Job;如果你需要更复杂的触发计划,你可以创建多个Trigger并指派它们给同一个Job。

1.2 Scheduler的创建方式

1.2.1 StdSchedulerFactory

  • Quartz默认使用的是StdSchedulerFactory。
  • 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器。
  • 配置参数一般存储在quartz.properties文件中。
  • 调用getScheduler方法就可以创建和初始化调度器对象。
StdSchedulerFactory fact = new StdSchedulerFactory();
Scheduler scheduler = fact.getScheduler();

1.2.1.1 输出调度器开始的时间:

    Date scheduleJob(JobDetail jobDetail, Trigger trigger)
throws SchedulerException;
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("当前时间是:"+new Date()); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); Date date = scheduler.scheduleJob(jobDetail, trigger);
System.out.println("调度器开始时间:" + date); scheduler.start(); } }

1.2.1.2 启动任务调度

void start() throws SchedulerException;

1.2.1.3 任务调度挂起,即暂停

void standby() throws SchedulerException;
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("当前时间是:"+new Date()); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException, InterruptedException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); //Scheduler执行2秒后自动挂起
Thread.sleep(2000L);
scheduler.standby(); //Scheduler执行5秒后自动开启
Thread.sleep(5000L);
scheduler.start(); } }

1.2.1.4 关闭任务调度

void shutdown() throws SchedulerException;

void shutdown(boolean waitForJobsToComplete)
throws SchedulerException;
  • 如果shutdown中的参数是true:表示等待所有正在执行的Job执行完毕之后,再关闭Scheduler。
  • 如果shutdown中的参数是false:表示直接关闭Scheduler。
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("当前时间是:"+new Date()); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException, InterruptedException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); Thread.sleep(2000L);
scheduler.shutdown(true); } }

1.2.2 DirectSchedulerFactory(了解)

  • DirectSchedulerFactory是对SchedulerFactory的直接实现,通过它可以直接构建Scheduler、ThreadPool等。
DirectSchedulerFactory directSchedulerFactory = DirectSchedulerFactory.getInstance();
Scheduler scheduler = directSchedulerFactory.getScheduler();

2 Quartz.properties

  • 默认路径是:quartzjar包中org.quartz中的quartz.properties。
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
# org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000 org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore

  • 我们也可以自己新建一个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.spi.ThreadPool接口的类,Quartz自带的线程池的实现类是org.quartz.simpl.SimpleThreadPool。
  • 作业存储设置:
  • 描述了调度器实例的生命周期中,Job和Trigger信息是如何存储的。
  • 插件配置:
  • 满足特定需求用到的Quartz插件的配置。

3 Quartz监听器

3.1 概述

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

3.2 JobListener

  • 任务调度的过程中,和任务Job相关的事件包括:Job开始要执行的提示。Job执行完成的提示。
package org.quartz;

public interface JobListener {

    String getName();

    void jobToBeExecuted(JobExecutionContext context);

    void jobExecutionVetoed(JobExecutionContext context);

    void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException); }
  • 其中:
  • getName方法:用于获取该JobListener的名称。
  • jobToBeExecuted方法:Scheduler在JobDetail将要被执行的时候调用这个方法。
  • jobExecutionVetoed方法:Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法。
  • jobWasExecuted方法:Scheduler在JobDetail被执行之后调用此方法。
  • 示例:全局JobListener
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println(this.getClass().getName() + "当前时间是:" + new Date());
}
}
  • MyJobListener.java
package com.sunxiaping;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener; public class MyJobListener implements JobListener {
@Override
public String getName() {
System.out.println("监听器的名称:" + this.getClass().getName());
return getClass().getName();
} @Override
public void jobToBeExecuted(JobExecutionContext context) {
System.out.println("Scheduler在JobDetail将要被执行的时候调用这个方法");
} @Override
public void jobExecutionVetoed(JobExecutionContext context) {
System.out.println("Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法");
} @Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
System.out.println("Scheduler在JobDetail被执行之后调用此方法");
}
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException, InterruptedException {
JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); //创建并创建一个全局的Job Listener
scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs()); scheduler.start(); } }
  • 示例:局部Listener
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println(this.getClass().getName() + "当前时间是:" + new Date());
}
}
  • MyJobListener.java
package com.sunxiaping;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener; public class MyJobListener implements JobListener {
@Override
public String getName() {
System.out.println("监听器的名称:" + this.getClass().getName());
return getClass().getName();
} @Override
public void jobToBeExecuted(JobExecutionContext context) {
System.out.println("Scheduler在JobDetail将要被执行的时候调用这个方法");
} @Override
public void jobExecutionVetoed(JobExecutionContext context) {
System.out.println("Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法");
} @Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
System.out.println("Scheduler在JobDetail被执行之后调用此方法");
}
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.KeyMatcher; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException, InterruptedException {
JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); //创建并创建一个局部的Job Listener
scheduler.getListenerManager().addJobListener(new MyJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1","group1"))); scheduler.start(); } }

3.3 TriggerListener

  • 任务调度过程中,和触发器Trigger相关的事件包括:触发器触发、触发器没有正常触发、触发器完成。
package org.quartz;

import org.quartz.Trigger.CompletedExecutionInstruction;

public interface TriggerListener {

    String getName();

    void triggerFired(Trigger trigger, JobExecutionContext context);

    boolean vetoJobExecution(Trigger trigger, JobExecutionContext context);

    void triggerMisfired(Trigger trigger);

    void triggerComplete(Trigger trigger, JobExecutionContext context,
CompletedExecutionInstruction triggerInstructionCode); }
  • 其中:
  • getName方法:用于获取触发器的名称。
  • TriggerFired方法:当和触发器相关联的Trigger被触发,Job上的execute()方法将被执行的时候,Scheduler就调用该方法。
  • vetoJobExecution方法:在Trigger触发后,Job将要被执行的时候由Scheduler调用这个方法。TriggerListener给了一个选择去否决Job的执行。假如这个方法返回true,这个Job将不会为此Trigger触发而得到执行。
  • triggerMisfired方法:Scheduler调用这个方法是在Trigger错过触发的时候。
  • triggerComplete方法:Trigger被触发并且完成了Job的执行的时候,Scheduler就调用了该方法。
  • 示例:
  • 略。

3.4 SchedulerListener

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

public interface SchedulerListener {

    void jobScheduled(Trigger trigger);

    void jobUnscheduled(TriggerKey triggerKey);

    void triggerFinalized(Trigger trigger);

    void triggerPaused(TriggerKey triggerKey);

    void triggersPaused(String triggerGroup);

    void triggerResumed(TriggerKey triggerKey);

    void triggersResumed(String triggerGroup);

    void jobAdded(JobDetail jobDetail);

    void jobDeleted(JobKey jobKey);

    void jobPaused(JobKey jobKey);

    void jobsPaused(String jobGroup);

    void jobResumed(JobKey jobKey);

    void jobsResumed(String jobGroup);

    void schedulerError(String msg, SchedulerException cause);

    void schedulerInStandbyMode();

    void schedulerStarted();

    void schedulerStarting();

    void schedulerShutdown();

    void schedulerShuttingdown();

    void schedulingDataCleared();
}
  • 其中:
  • jobScheduled方法:用于部署JobDetail时被调用。
  • jobUnscheduled方法:用于卸载JobDetail时被调用。
  • triggerFinalized方法:当一个Trigger来到了再也不会触发的状态时调用这个方法。除非这个Job已经设置成了持久性,否则它就会从Scheduler中移除。
  • triggersPaused方法:Scheduler调用这个方法是发生在一个Trigger或Trigger组被暂停时。假如是Trigger组的话,triggerName参数将为null。
  • triggersResumed方法:Scheduler调用这个方法是发生成一个Trigger或Trigger组从暂停中恢复时。假如是Trigger组的话,triggerName的参数将为null。
  • jobsPaused方法:当一个或一组JobDetail暂停时调用这个方法。
  • jobsResumed方法:当一个或一组Job从暂停上恢复时调用这个方法。
  • schedulerError方法:在Scheduler的正常运行期间产生一个严重错误的时候调用这个方法。
  • schedulerStarted方法:在Scheduler开启的时候,调用该方法。
  • schedulerStandbyMode方法:当Scheduler处于StandBy模式,调用该方法。
  • schedulerShutdown方法:当Scheduler停止的时候,调用该方法。
  • schedulingDataCleared方法:当Scheduler的数据被清除的时候,调用该方法。
  • 示例:
  • 略。

Quartz(二)的更多相关文章

  1. 开源定时任务框架Quartz(二)

    概述 上一篇文章完成了第一个Quartz程序的编写,这篇从Quartz中的几个重要对象来更深一层认识Quartz框架. Job和JobDetail Job是Quartz中的一个接口,接口下只有exec ...

  2. Quartz (二) 和Spring整合

    先给个场景:每五分钟扫描并关闭7天未付款的订单 1.quartz pom.xml依赖 <dependencies> <dependency> <groupId>or ...

  3. quartz (二) Spring+Quartz实现定时任务的配置方法

    JobDetail  设置执行的任务 :CronTrigger   触发器:设置执行的时间规则      ;  Scheduler    // 调度器,将任务与执行时间关联 本文转自:http://w ...

  4. quartz.net 使用(一)-执行定时计划任务

    一.使用nuget安装所需要的包 Install-Package Quartz 二.实现自己的job继承IJob public class FirstJob : IJob { public void ...

  5. ASP.NET quartz 定时任务

    1.下载 2.使用例子 Demo 概述:Quartz 是开源的定时任务工具类,默认每隔10秒执行一次任务,相当于C#的Timer,不断的循环执行(Start 方法),也可以随时停止(ShutDown方 ...

  6. windows服务autofac注入quartz任务

    一.nuget下载相关类库引用 install-package Quartz install-package Autofac install-package Autofac.Configuration ...

  7. Spring(十)Spring任务调度

    一.计划任务 需要定时执行一些计划(定时更新等),这样的计划称之为计划任务 Spring抽象封装了Java提供的Timer与TimerTask类 也可以使用拥有更多任务计划功能的Quartz 二.Ti ...

  8. 最全spring boot视频系列,你值得拥有

    ================================== 从零开始学Spring Boot视频 ================================== àSpringBoot ...

  9. 1.spring boot起步之Hello World【从零开始学Spring Boot】

    [视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm ...

  10. 0. 前言【从零开始学Spring Boot】

    [视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm ...

随机推荐

  1. mybatis 动态SQL .1

    MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还要注意去掉 ...

  2. NFA转换为等价的DFA

    在编译系统中,词法分析阶段是整个编译系统的基础.对于单词的识别,有限自动机FA是一种十分有效的工具.有限自动机由其映射f是否为单值而分为确定的有限自动机DFA和非确定的有限自动机NFA.在非确定的有限 ...

  3. Shell编程、part3

    本节内容 1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变 ...

  4. 【Ruby on Rails 学习五】Ruby语言的方法

    1.方法的调用 2.自定义方法 3.带默认值的自定义方法 4.带返回值的自定义方法 方法或者说是函数,实际上是包含了一段代码,去执行某一个特定的过程. def add(a=3,b=2) return ...

  5. tensorflow-2.0 技巧 | ImageNet 归一化

    _MEAN_RGB = [123.15, 115.90, 103.06] def _preprocess_subtract_imagenet_mean(inputs): ""&qu ...

  6. Akka系列(八):Akka persistence设计理念之CQRS

    前言........ 这一篇文章主要是讲解Akka persistence的核心设计理念,也是CQRS(Command Query Responsibility Segregation)架构设计的典型 ...

  7. 红帽学习记录[RHCE] ISCSI远程块储存

    目录 iSCSI 定义 组件术语 启动器 目标 ACL 发现 IQN 登录 LUN 节点 门户 TPG 搭建一个iSCSI服务 提供一个iSCSI目标 配置iSCSI客户端 iSCSI 定义 SCSI ...

  8. 【转帖】Linux系统上面qemu 模拟arm

    零基础在Linux系统搭建Qemu模拟arm https://blog.csdn.net/weixin_42489042/article/details/81145038 自己没搞定 改天再试试 感谢 ...

  9. CentOS7之root密码破解

    1.重新启动Linux系统,在出现引导界面时上下移动光标选择第一引导项,按下键盘的“e”键进入内核编辑界面,如图所示: 2.找到linux16参数这一行,按住“Ctrl+e”组合键跳转到行尾,添加rd ...

  10. TCP协议的粘包现象和解决方法

    # 粘包现象 # serverimport socket sk = socket.socket()sk.bind(('127.0.0.1', 8005))sk.listen() conn, addr ...