quartZ
注:本文章只是自己在学习中记的笔记(可能有点乱),只提供参考。如有错误请指出。
一.简介
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能
- 持久性作业 - 就是保持调度定时的状态;
- 作业管理 - 对调度作业进行有效的管理;
官网:http://www.quartz-scheduler.org/
二.QuartZ设计模式
- Builder模式
- Factory模式
- 组件模式
- 链式编程
三.核心概念
-
任务Job
Job就是你想实现的任务类,每一个Job必须实现org.quartz.Job接口,且只需实现接口定义的方法execute()即可
graph BT B(自定义的实现类)-.<font color=#ccc>实现</font>.->A(<Interface>org.quartz.Job)
-
触发器Trigger
Trigger为你执行任务的触发器,触发器Trigger最基本的功能是指定Job的执行时间,执行间隔,运行次数等。
Quartz 提供了四种类型的 Trigger,但其中两种是最为常用的,分别是:SimpleTrigger 和 CronTrigger
graph BT
a1(SimpleTrigger) -.-> B(<Interface>Trigge)
a2(CronTrigger) -.<font color=#ccc>实现</font>.-> B(<Interface>Trigge)
a3(自定义的Trigger) -.-> B(<Interface>Trigge)
-
调度器Scheduler
Scheduler为任务调度器,它会将任务job和触发器Trigger整合起来,负责基于Trigger设定的时间来执行job
graph TB a1(<Interface>Scheduler) ==<font color=#ccc>调度</font>==> a2(Trigger) a1(<Interface>Scheduler) ==<font color=#ccc>调度</font>==> a3(JOB)
四.QuartZ几个常用的API
-
Schedule用于调度程序交互的主程序接口
Schedule调度程序-任务执行计划表,只有安排进执行计划的任务job(通过scheduler.scheduleJob方法安排进执行计划),当它预先定义的执行时间到了的时候(任务触发Tigger),该任务才会执行
-
Job 我们预先定义的希望在未来时间能被调度程序执行的任务类,我们可以自己定义
-
JobDetail 使用JobDetail来定义任务的实例。JobDetail通过jobbuilder来创建的
-
JobDataMap 可以包含不限量(序列化)的对象,在job实例执行的时候,可以使用其中的数据。jobMap是Java map中的一个实现类,额外增加了一些便于存取基本类型的数据的方法
-
Tigger 触发器,Tigger对象是用来触发执行job的,当调度一个job时,我们实例一个触发器,然后调整他的属性来满足job的执行的条件,比如每3秒执行一次
-
jobBuilder 用于声明一个任务实例,也可以定义该任务的详情,比如任务名,组名,这个申明的实例将会作为一个实际执行的任务
-
TiggerBuilder 触发器创建器,用于创建tagger实例
-
jobListener,tiggerlistener,schedulelistener监听器。用于对组件的监听
五.QuartZ的使用
-
准备工作(创建项目,导入jar包)
<!--定时调度任务--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.3.2</version> </dependency>
-
创建j我们要做定时任务的类(实现org.quartz.Job)
import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class MyJob implements Job { public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH-mm-ss"); String date = format.format(new Date()); System.out.println(date); } }
-
创建Schedule,执行任务
import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; /** * @author shkstart * @create 2020-03-11 15:22 */ public class QuartzTest { public static void main(String[] args) throws Exception { //创建调度器Scheduler方式一 //Scheduler scheduler1 = StdSchedulerFactory.getDefaultScheduler(); //创建调度器Scheduler方式二 StdSchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); //创建JobDetail实例,并与quartZ类绑定(Job执行内容) JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("h1", "group1").usingJobData("count","11111").build(); //触发器 SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("t1", "group1") .startNow()//立即执行 .withSchedule(SimpleScheduleBuilder.simpleSchedule()//simpleSchedule触发器 .withIntervalInSeconds(5)//几秒执行一次 .repeatForever()//一直执行 ).build(); //执行,让调度器关联任务和触发器 scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
-
运行main方法,可以看到控制台每5秒打印一次时间
六.Quartz核心详解
-
job和JobDetail介绍
-
job:工作任务调用的接口,任务类需要实现该类,重写该类的execute()方法。
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //业务代码 //jobExecutionContext可以获取JobDataMap里传入的数据 }
-
JobDetail:绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。重要属性有name,group,jobClass,jobDataMap
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)//传入自定义实现Job的任务类 .withIdentity("h1","group1")//定义name,group .usingJobData("count","11111")//JobDataMap实现了JDK的Map接口,可以以Key-Value的形式存储数据。 .build();
-
-
JobExecutionContext:中包含了Quartz运行时的环境以及Job本身的详细数据信息。
当Schedule调度执行一个Job的时候,就会将JobExecutionContext传递给该Job的execute()中,Job就可以通过JobExecutionContext对象获取信息。public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobKey jobKey = jobExecutionContext.getJobDetail().getKey(); System.out.println(jobKey.getName()+"-----"+jobKey.getGroup());//获取到jobDetail里定义的name和group JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();//拿到jobDataMap里传入的jobDataMap数据。就是这一句 .usingJobData("count","11111")。 String count = jobDataMap.getString("count");//根据key获取value值 System.out.println(count); //可以拿到很多数据,可以拿到jobDetail,相反也可以拿到tigger里的数据。还可以拿到其他比如任务名称等数据... }
打印数据为: h1-----group1 11111
-
Trigger、SimpleTrigger、CronTrigger
-
Trigger:rigger是Quartz的触发器,会去通知Scheduler何时去执行对应Job。
-
SimpleTrigger:SimpleTrigger可以实现在一个指定时间段内执行一次作业任务或一个时间段内多次执行作业任务。
下面的程序就实现了程序运行5s后开始执行Job,执行Job 5s后结束执行: -
CronTrigger:CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的,先了解下Cron表达式:
由7个子表达式组成字符串的,格式如下:[秒] [分] [小时] [日] [月] [周] [年]
如果不知道什么写,可通过在线生成Cron表达式的工具:http://cron.qqe2.com/ 来生成自己想要的表达式。
//写法跟SimpleTrigger一样,就是withSchedule传入的触发器不一样和返回值不一样。 CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1") .usingJobData("trigger1", "这是jobDetail1的trigger") .startNow()//立即生效 //.startAt(startDate) .endAt(endDate) .withSchedule(CronScheduleBuilder.cronSchedule("* 30 10 ? * 1/5 2018"))//使用CronTrigger来进行定时。每周一到周五上午10:30执行定时任务 .build();
-
网友评论