Quartz任务调度

您所在的位置:网站首页 quartz调度原理 Quartz任务调度

Quartz任务调度

2022-12-28 02:12| 来源: 网络整理| 查看: 265

Quartz概念

Quartz是openSymphony开源组织在Job scheduling领域的开源项目,它可以与J2EE与J2SE应用程序相结合,也可以单独使用。

Quartz是开源且具有丰富特性的“任务调度库”,能够集成于任何的Java应用,小到独立的应用,大到电子商业系统。Quartz能够创建亦简单亦复杂的调度,以执行上百、千,甚至上万的任务。任务job被定义为标准的Java组件,能够执行任何你想要实现的功能。

官网:http://www.quartz-scheduler.org/

Quartz运行环境

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

Quartz设计模式

Builder模式 Factory模式 组件模式 链式模式

Quartz的核心概念

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

2、触发器Trigger Trigger为你执行任务的触发器。不如说每天定时3点发送一份统计邮件,Trigger将会设置3点进行执行该任务。 Trigger主要包含两种: SimpleTrigger 和 CronTrigger两种。

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

Quartz的体系结构

在这里插入图片描述

Quartz的几个常用API

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

1、Scheduler 用于与调度程序交互的主程序接口 Scheduler调度程序通过任务执行计划表,只有安排进执行计划的任务Job(通过scheduler.scheduleJob方法安排进执行计划),当它预先定义的执行时间到了的时候(任务触发trigger),该任务才会执行。

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

3、JobDetail 使用JobDetail来定义定时任务的实例,JobDetail实例通过JobBuilder类创建的。

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

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

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

7、TriggerBuilder 触发器创建器,用于创建触发器trigger实例

8、JobListener、TriggerListener、SchedulerListener监听器,用于对组件的监听

Quartz的使用 入门案例

新建maven项目,导入依赖

org.quartz-scheduler quartz 2.3.0 org.quartz-scheduler quartz-jobs 2.3.0

创建HelloJob任务类

package com.affection.quartz.job; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.text.SimpleDateFormat; import java.util.Date; /** * @author 邢道荣 * @date 2022/12/9 14:25 */ public class HelloJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 输出当前时间 Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = sdf.format(date); // 工作内容 System.out.println("数据库正在进行备份,备份时间是:" + dateString); } }

然后创建任务调度类HelloSchedulerDemo

package com.affection.quartz.job; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; /** * @author 邢道荣 * @date 2022/12/9 14:30 */ public class HelloSchedulerDemo { public static void main(String[] args) throws Exception { // 1、调度器(Scheduler) Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 2、任务实例(JobDetail) JobDetail jobDetail = JobBuilder.newJob(HelloJob.class) .withIdentity("job1", "group1") //参数1: 任务的名称(唯一实例); 参数二: 任务组的名称 .build(); // 3、触发器(Trigger) Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("trigger1", "group1") // 参数1:触发器的名称(唯一实例); 参数2:触发器组的名称 .startNow() // 马上启动触发器 .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1)) .build(); // 让调度器关联任务和触发器,保证按照触发器定义的条件执行任务 scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } } 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

JobExecutionContext介绍

当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法;

Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

public class HelloJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 输出当前时间 Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = sdf.format(date); // 工作内容 System.out.println("数据库正在进行备份,备份时间是:" + dateString); JobKey jobKey = context.getJobDetail().getKey(); System.out.println("工作任务名称:" + jobKey.getName() + "; 工作任务的组:" + jobKey.getGroup()); System.out.println("任务类的名称:" + context.getJobDetail().getJobClass().getSimpleName()); } } JobDataMap介绍

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

public class HelloJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 输出当前时间 Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = sdf.format(date); // 工作内容 System.out.println("数据库正在进行备份,备份时间是:" + dateString); JobKey jobKey = context.getJobDetail().getKey(); System.out.println("工作任务名称:" + jobKey.getName() + "; 工作任务的组:" + jobKey.getGroup()); System.out.println("任务类的名称:" + context.getJobDetail().getJobClass().getName()); System.out.println("任务类的名称:" + context.getJobDetail().getJobClass().getSimpleName()); // 从JobDetail对象中获取JobDataMap的数据 JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); String message = jobDataMap.getString("message"); System.out.println("任务数据的参数值:" + message); // 获取Trigger对象中获取jobDataMap的数据 JobDataMap jobDataMapTrigger = context.getTrigger().getJobDataMap(); String messageTriagger = jobDataMapTrigger.getString("message"); System.out.println("触发器数据的参数值:" + messageTriagger); // 获取Trigger的内容 TriggerKey triggerKey = context.getTrigger().getKey(); System.out.println("触发器名称:" + triggerKey.getName() + " ; 触发器组: " + triggerKey.getGroup()); } } public class HelloSchedulerDemo { public static void main(String[] args) throws Exception { // 1、调度器(Scheduler) Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 2、任务实例(JobDetail) JobDetail jobDetail = JobBuilder.newJob(HelloJob.class) .withIdentity("job1", "group1") //参数1: 任务的名称(唯一实例); 参数二: 任务组的名称 .usingJobData("message", "打印日志") // 传递参数,名称message .build(); // 3、触发器(Trigger) Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("trigger1", "group1") // 参数1:触发器的名称(唯一实例); 参数2:触发器组的名称 .startNow() // 马上启动触发器 .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1)) .usingJobData("message", "simple触发器") // 传递参数,名称 message .build(); // 让调度器关联任务和触发器,保证按照触发器定义的条件执行任务 scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }

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

public class HelloJob implements Job { private String message; public void setMessage(String message) { this.message = message; } @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println(message); } }

如果遇到同名的key,Trigger中的usingJobData会覆盖JobDetail中的usingJobData。

有状态的Job与无状态的Job

@PersistJobDataAfterExecution注解的使用

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

@PersistJobDataAfterExecution // 多次调用Job的时候,会对Job进行持久化,即保存一个数据的信息 public class HelloJob implements Job { private Integer count; public void setCount(Integer count) { this.count = count; } @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 累加count ++count; // 将count存放到JobDataMap中 context.getJobDetail().getJobDataMap().put("count", count); System.out.println("count的数量:" + count); } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3