Quartz 基本使用
Quartz 基本使用
- 一、Quartz的核心概念
- 二、Quartz的几个常用API
- 三、Quartz的使用
- 四、Quartz核心详解
- 五、JobListener
- 六、TriggerListener
- 七、SchedulerListener
一、Quartz的核心概念
Quartz [kwɔːts] 是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
1.持久性作业 - 就是保持调度定时的状态;
2.作业管理 - 对调度作业进行有效的管理;
Quartz是一个强大任务调度框架,可以用来干嘛?如一个OA系统需要在每周五9点自动生成数据报表,或者想每月10号自动还款,又或者每周给暗恋的女生定时发送邮件等等。下面介绍Quartz的三个核心概念(job,Trigger,Scheduler)。
1,任务job
job就是你想实现的任务类,每一个job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。
Job:工作任务调度的接口,任务类需要实现该接口,该接口中定义execute方法,类似jdk提供的TimeTask类的run方法,在里面编写任务执行的业务逻辑。
Job:实例在Quartz中的生命周期,每次调度器执行job时它在调用execute方法前,会创建一个新的job实例,当调用完成后,关联的job对象实例会被是释放,释放的实例会被垃圾回收机制回收。
2,触发器Trigger
Trigger 为你执行任务的触发器,比如你想每天定时1点发送邮件,Trigger将会设置1点执行该任务。
Trigger主要包含两种:SimpleTrigger和CronTriggerr。
3,调度器Scheduler
Scheduler是任务的调度器,会将任务job和触发器TRigger结合,负责基于Trigger设定的时间执行job。
二、Quartz的几个常用API
Scheduler :用于与调度程序交互的主程序接口。
Job :预先定义的希望在未来时间被调度程序执行的任务类,自定义。
JobDetall :使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建。
JobDataMap :可包含数据对象,在job实例执行的是好,可使用包含的数据;JobDataMap是java Map接口的实现,增加了一些存取基本类型方法。
Trgger触发器 :Trigger对象是用于触发执行Job的,当调度一个Job时,我们实例一个触发器然后调整它的属性来满足Job执行的条件,表明任务在什么时候执行。定义了一个已经被安排的任务将在什么时候执行的时间条件,比如每秒执行一次。
JobBuilder :用于声明一个任务实例,也可以定义关于该任务的详情比如:任务名,组名等,这个声明的实例将作为一个实例执行的任务。
TriggerBuilder :触发器创建器,用于创建触发器trigger实例。
JobListener,TriggerListener,SchedulerListener监听器,用于对组件的监听。
三、Quartz的使用
创建项目并加入依赖
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.1</version>
</dependency>
新建一个能够打印任意内容的Job:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;public class PrintWordsJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) {String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));}
}
创建Schedule,执行任务:
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.concurrent.TimeUnit;public class MyScheduler {public static void main(String[] args) throws SchedulerException, InterruptedException {// 1、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class).withIdentity("job1", "group1").build();// 2、构建Trigger实例,每隔1s执行一次Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1").startNow()//立即生效.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)//每隔1s执行一次.repeatForever()).build();//一直执行//3、创建调度器Scheduler并执行Scheduler scheduler = new StdSchedulerFactory().getScheduler();scheduler.scheduleJob(jobDetail, trigger);System.out.println("--------scheduler start ! ------------");scheduler.start();//睡眠TimeUnit.MINUTES.sleep(1);scheduler.shutdown();System.out.println("--------scheduler shutdown ! ------------");}
}
运行程序,可以看到程序每隔1s会打印出内容,且在一分钟后结束。
四、Quartz核心详解
1.Job和JobDetail
Job是Quartz中的一个接口,接口下只有execute方法,在这个方法中编写业务逻辑。
JobDetail用来绑定Job,为Job实例提供许多属性:
name group jobClass jobDataMap
JobDetail绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
为什么设计成JobDetail + Job,不直接使用Job
JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。 这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。
2.Trigger、SimpleTrigger、CronTrigger
Trigger
Trigger是Quartz的触发器,会去通知Scheduler何时去执行对应Job。
new Trigger().startAt():表示触发器首次被触发的时间;
new Trigger().endAt():表示触发器结束触发的时间;
SimpleTrigger
SimpleTrigger可以实现在一个指定时间段内执行一次作业任务或一个时间段内多次执行作业任务。
下面的程序就实现了程序运行5s后开始执行Job,执行Job 5s后结束执行:
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 5000);Date endDate = new Date();
endDate.setTime(startDate.getTime() + 5000);Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1").usingJobData("trigger1", "这是jobDetail1的trigger").startNow()//立即生效.startAt(startDate).endAt(endDate).withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)//每隔1s执行一次.repeatForever()).build();//一直执行
CronTrigger
CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的,先了解下Cron表达式: 由7个子表达式组成字符串的,格式如下:
[秒] [分] [小时] [日] [月] [周] [年]
Cron表达式的语法比较复杂,
如:* 30 10 ? * 1/5 * 表示(从后往前看)
[指定年份] 的[ 周一到周五][指定月][不指定日][上午10时][30分][指定秒]
又如:00 00 00 ? * 10,11,12 1#5 2018
表示2018年10、11、12月的第一周的星期五这一天的0时0分0秒去执行任务。
在线生成corn表达式:http://cron.qqe2.com/
下面的代码就实现了每到整分时执行一次定时任务
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;public class MyScheduler2 {public static void main(String[] args) throws SchedulerException, InterruptedException {//1.创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)JobDetail jobDetail=JobBuilder.newJob(PrintWordsJob.class).usingJobData("jobDetail", "这个Job用来测试的").withIdentity("job","group").build();//2.触发器CronTrigger trigger=TriggerBuilder.newTrigger().withIdentity("trigger", "group").startNow()//立刻执行.usingJobData("trigger1", "这是jobDetail1的trigger").withSchedule(CronScheduleBuilder.cronSchedule("0 * * * * ?"))//表示每次0秒时候执行。.build();//3.调度器Scheduler scheduler = new StdSchedulerFactory().getScheduler();scheduler.scheduleJob(jobDetail,trigger);System.out.println("--------scheduler start ! ------------");scheduler.start();System.out.println("--------scheduler shutdown ! ------------");}
}
五、JobListener
创建MyJobListener实现JobListener接口
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;public class MyJobListener implements JobListener {public String getName() {return this.getClass().getSimpleName();}//Scheduler在jobDetail将要被执行时调用这个方法(执行前)public void jobToBeExecuted(JobExecutionContext context) {String jobName = context.getJobDetail().getKey().getName();System.out.println("我的job名1:" + jobName);}//Scheduler在jobDetail即将被执行,但又被TriggerListermer 否定时会调用该方法public void jobExecutionVetoed(JobExecutionContext context) {String jobName = context.getJobDetail().getKey().getName();System.out.println("我的job名2:" + jobName);}//Scheduler在jobDetail即将被执行之后调用这个方法。(执行后)public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {String jobName = context.getJobDetail().getKey().getName();System.out.println("我的job名3:" + jobName);}
}
在scheduler创建后加入监听即可生效
scheduler.getListenerManager().addJobListener(new MyJobListener());
六、TriggerListener
任务调度过程中,与触发器Trigger相关的事件包括:触发器触发,触发器未正常触发,触发器完成等。
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;public class MyTriggerListener implements TriggerListener {//用于获取触发器的名称 public String getName() {//获取默认类名return this.getClass().getSimpleName();}//当与监听器相关联的trigger被触发,job上的execute()方法将被执行时,Scheduler就调用该方法public void triggerFired(Trigger trigger, JobExecutionContext context) {System.out.println("triggerFired");}//在Trigger触发后,job将要被执行时由Scheduler调用这个方法。//TriggerListener给一个选择去否决job的执行。如方法返回true,job此次将不会为trigger触发执行。false,放行。public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {System.out.println("vetoJobExecution");return false;}//Scheduler 调用这个方法是在trigger错过时触发。public void triggerMisfired(Trigger trigger) {System.out.println("triggerMisfired");}//triggerComplete:trigger被触发并且完成了job的执行时,Scheduler调用这个方法。public void triggerComplete(Trigger trigger, JobExecutionContext context,Trigger.CompletedExecutionInstruction triggerInstructionCode) {System.out.println("triggerComplete");}}
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener());
七、SchedulerListener
SchedulerListener会在scheduler的生命周期中关键事件发生时被调用,与Scheduler有关事件;增加或者删除一个 job/trigger,关闭scheduler等。
import org.quartz.*;public class MySchedulerListener implements SchedulerListener {//用于部署JobDetail 的时候调用public void jobScheduled(Trigger trigger) {String name = trigger.getKey().getName();System.out.println("获取触发器名称:"+name);}//卸载JobDetail 的时候调用public void jobUnscheduled(TriggerKey triggerKey) {System.out.println(triggerKey.getName());}//当trigger来到再也不会触发的时候调用这个方法public void triggerFinalized(Trigger trigger) {String name = trigger.getKey().getName();System.out.println("获取触发器名称:"+name);}//当trigger 被暂停时候调用public void triggerPaused(TriggerKey triggerKey) {System.out.println("被暂停1");}//当trigger组 被暂停时候调用public void triggersPaused(String triggerGroup) {System.out.println("被暂停2");}///当trigger从 被暂停 到恢复 时候 调用public void triggerResumed(TriggerKey triggerKey) {System.out.println("恢复");}///当trigger组从 被暂停 到恢复 时候 调用public void triggersResumed(String triggerGroup) {System.out.println("恢复");}//添加工作任务调用public void jobAdded(JobDetail jobDetail) {System.out.println("添加工作任务");}//删除工作任务public void jobDeleted(JobKey jobKey) {System.out.println("删除工作任务");}public void jobPaused(JobKey jobKey) {// TODO Auto-generated method stub}public void jobsPaused(String jobGroup) {// TODO Auto-generated method stub}public void jobResumed(JobKey jobKey) {// TODO Auto-generated method stub}public void jobsResumed(String jobGroup) {// TODO Auto-generated method stub}//scheduler产生Error调用public void schedulerError(String msg, SchedulerException cause) {// TODO Auto-generated method stub}//scheduler被挂起时候调用public void schedulerInStandbyMode() {// TODO Auto-generated method stub}//scheduler开启的时候调用public void schedulerStarted() {System.out.println("scheduler kai qi ");}//scheduler 正在开启的时候调用 ing.....public void schedulerStarting() {System.out.println("scheduler 正在开启的时候调用 ing.....");}scheduler关闭 的时候调用public void schedulerShutdown() {System.out.println("scheduler关闭 的时候调用");}//scheduler 正在关闭的时候调用 ing.....public void schedulerShuttingdown() {System.out.println("//scheduler 正在关闭的时候调用 ing.....");}//scheduler 数据被清除了的时候调用public void schedulingDataCleared() {System.out.println("//scheduler 数据被清除了的时候调用");}}
scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
Quartz 基本使用相关推荐
- SpringBoot中实现quartz定时任务
Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...
- Java基于Quartz的定时任务调度服务(一)
Quartz的基本用法 一 Quartz的简单介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现,一个优秀的开源调度框架,其特点是:强大的 ...
- springboot整合Quartz实现动态配置定时任务
版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/liuchuanhong1/article/details/60873295 前言 在我们日常的开发中,很多 ...
- Quartz 2D Programming Guide笔记
###Graphics Contexts图形上下文### 图形上下文(graphics context)是绘制目标,可以理解为画布,包含着绘图时的参数和设备信息.类型为CGContextRef.获取g ...
- 【Quartz】实现接口封装化(二)
原文:[Quartz]实现接口封装化(二) 前言 通过昨天的努力终于算是了解Quartz这个定时器的简单使用,为了更深一步的了解和基于以后希望在项目中能使用他.所有我对他做了一下简单的封装操作 ...
- quartz在集群环境下的最终解决方案
在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...
- 将Quartz.NET集成到 Castle中
Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架.AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务. ...
- 初识Quartz(三)
为什么80%的码农都做不了架构师?>>> 简单作业: package quartz_project.example3;import java.util.Date;import ...
- java timer cron_Java之旅--定时任务(Timer、Quartz、Spring、LinuxCron)
在Java中,实现定时任务有多种方式.本文介绍4种.Timer和TimerTask.Spring.QuartZ.Linux Cron. 以上4种实现定时任务的方式.Timer是最简单的.不须要不论什么 ...
- Quartz动态添加、修改和删除定时任务
2019独角兽企业重金招聘Python工程师标准>>> Quartz动态添加.修改和删除定时任务 转载于:https://my.oschina.net/haokevin/blog/1 ...
最新文章
- PCB板查短路点的一种技巧 (转载)
- C++ enum 枚举
- Git内部原理之深入解析传输协议
- 网管菜鸟第一步:两年后必须跳槽『博客之星访谈』
- linux笔记 第十七天 加密技术、openssl详解
- Python str 与 bytes 类型(Python2/3 对 str 的处理)
- 洛谷P3378 【模板】堆
- Oracle的去重函数 distinct
- SpringBoot启动类自动包扫描 三种方式
- Windows Server 2003 SP2 中文版下载
- Maven pom.xml中的元素modules、parent、properties以及import(转)
- php怎么显示好看的字体颜色,网页中字体颜色设置方法的总结
- 矩阵 向量 线性变换 基变换
- 腾讯云TCA运维工程师认证题库及例题示范
- 射频电路学习之LC振荡电路
- linux配置163镜像,修改yum使用163开源镜像升级CentOS
- 微博第三方登录django+vue
- PTA 选择结构 7-1 能买手机吗?
- 微信openid 服务器备案,微信生态中的 openId、unionID和业务系统中的ID
- 李宏毅——一天搞懂深度学习PPT学习笔记