quartZ
注:本文章只是自己在學(xué)習(xí)中記的筆記(可能有點(diǎn)亂)茎芋,只提供參考攒驰。如有錯(cuò)誤請(qǐng)指出项戴。
一.簡(jiǎn)介
Quartz是OpenSymphony開源組織在Job scheduling領(lǐng)域又一個(gè)開源項(xiàng)目宛裕,完全由Java開發(fā)穆碎,可以用來執(zhí)行定時(shí)任務(wù)牙勘,類似于java.util.Timer。但是相較于Timer所禀, Quartz增加了很多功能
- 持久性作業(yè) - 就是保持調(diào)度定時(shí)的狀態(tài);
- 作業(yè)管理 - 對(duì)調(diào)度作業(yè)進(jìn)行有效的管理;
官網(wǎng):http://www.quartz-scheduler.org/
二.QuartZ設(shè)計(jì)模式
- Builder模式
- Factory模式
- 組件模式
- 鏈?zhǔn)骄幊?/li>
三.核心概念
-
任務(wù)Job
Job就是你想實(shí)現(xiàn)的任務(wù)類方面,每一個(gè)Job必須實(shí)現(xiàn)org.quartz.Job接口,且只需實(shí)現(xiàn)接口定義的方法execute()即可
graph BT B(自定義的實(shí)現(xiàn)類)-.<font color=#ccc>實(shí)現(xiàn)</font>.->A(<Interface>org.quartz.Job)
-
觸發(fā)器Trigger
Trigger為你執(zhí)行任務(wù)的觸發(fā)器色徘,觸發(fā)器Trigger最基本的功能是指定Job的執(zhí)行時(shí)間恭金,執(zhí)行間隔,運(yùn)行次數(shù)等褂策。
Quartz 提供了四種類型的 Trigger横腿,但其中兩種是最為常用的,分別是:SimpleTrigger 和 CronTrigger
graph BT
a1(SimpleTrigger) -.-> B(<Interface>Trigge)
a2(CronTrigger) -.<font color=#ccc>實(shí)現(xiàn)</font>.-> B(<Interface>Trigge)
a3(自定義的Trigger) -.-> B(<Interface>Trigge)
-
調(diào)度器Scheduler
Scheduler為任務(wù)調(diào)度器辙培,它會(huì)將任務(wù)job和觸發(fā)器Trigger整合起來蔑水,負(fù)責(zé)基于Trigger設(shè)定的時(shí)間來執(zhí)行job
graph TB a1(<Interface>Scheduler) ==<font color=#ccc>調(diào)度</font>==> a2(Trigger) a1(<Interface>Scheduler) ==<font color=#ccc>調(diào)度</font>==> a3(JOB)
四.QuartZ幾個(gè)常用的API
-
Schedule用于調(diào)度程序交互的主程序接口
Schedule調(diào)度程序-任務(wù)執(zhí)行計(jì)劃表,只有安排進(jìn)執(zhí)行計(jì)劃的任務(wù)job(通過scheduler.scheduleJob方法安排進(jìn)執(zhí)行計(jì)劃)扬蕊,當(dāng)它預(yù)先定義的執(zhí)行時(shí)間到了的時(shí)候(任務(wù)觸發(fā)Tigger)搀别,該任務(wù)才會(huì)執(zhí)行
Job 我們預(yù)先定義的希望在未來時(shí)間能被調(diào)度程序執(zhí)行的任務(wù)類,我們可以自己定義
JobDetail 使用JobDetail來定義任務(wù)的實(shí)例尾抑。JobDetail通過jobbuilder來創(chuàng)建的
JobDataMap 可以包含不限量(序列化)的對(duì)象歇父,在job實(shí)例執(zhí)行的時(shí)候,可以使用其中的數(shù)據(jù)再愈。jobMap是Java map中的一個(gè)實(shí)現(xiàn)類榜苫,額外增加了一些便于存取基本類型的數(shù)據(jù)的方法
Tigger 觸發(fā)器,Tigger對(duì)象是用來觸發(fā)執(zhí)行job的翎冲,當(dāng)調(diào)度一個(gè)job時(shí)垂睬,我們實(shí)例一個(gè)觸發(fā)器,然后調(diào)整他的屬性來滿足job的執(zhí)行的條件抗悍,比如每3秒執(zhí)行一次
jobBuilder 用于聲明一個(gè)任務(wù)實(shí)例驹饺,也可以定義該任務(wù)的詳情,比如任務(wù)名缴渊,組名赏壹,這個(gè)申明的實(shí)例將會(huì)作為一個(gè)實(shí)際執(zhí)行的任務(wù)
TiggerBuilder 觸發(fā)器創(chuàng)建器,用于創(chuàng)建tagger實(shí)例
jobListener,tiggerlistener,schedulelistener監(jiān)聽器衔沼。用于對(duì)組件的監(jiān)聽
五.QuartZ的使用
-
準(zhǔn)備工作(創(chuàng)建項(xiàng)目蝌借,導(dǎo)入jar包)
<!--定時(shí)調(diào)度任務(wù)--> <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>
-
創(chuàng)建j我們要做定時(shí)任務(wù)的類(實(shí)現(xiàn)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); } }
-
創(chuàng)建Schedule昔瞧,執(zhí)行任務(wù)
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 { //創(chuàng)建調(diào)度器Scheduler方式一 //Scheduler scheduler1 = StdSchedulerFactory.getDefaultScheduler(); //創(chuàng)建調(diào)度器Scheduler方式二 StdSchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); //創(chuàng)建JobDetail實(shí)例,并與quartZ類綁定(Job執(zhí)行內(nèi)容) JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("h1", "group1").usingJobData("count","11111").build(); //觸發(fā)器 SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("t1", "group1") .startNow()//立即執(zhí)行 .withSchedule(SimpleScheduleBuilder.simpleSchedule()//simpleSchedule觸發(fā)器 .withIntervalInSeconds(5)//幾秒執(zhí)行一次 .repeatForever()//一直執(zhí)行 ).build(); //執(zhí)行,讓調(diào)度器關(guān)聯(lián)任務(wù)和觸發(fā)器 scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
運(yùn)行main方法菩佑,可以看到控制臺(tái)每5秒打印一次時(shí)間
六.Quartz核心詳解
-
job和JobDetail介紹
-
job:工作任務(wù)調(diào)用的接口自晰,任務(wù)類需要實(shí)現(xiàn)該類,重寫該類的execute()方法擎鸠。
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //業(yè)務(wù)代碼 //jobExecutionContext可以獲取JobDataMap里傳入的數(shù)據(jù) }
-
JobDetail:綁定指定的Job缀磕,每次Scheduler調(diào)度執(zhí)行一個(gè)Job的時(shí)候缘圈,首先會(huì)拿到對(duì)應(yīng)的Job劣光,然后創(chuàng)建該Job實(shí)例,再去執(zhí)行Job中的execute()的內(nèi)容糟把,任務(wù)執(zhí)行結(jié)束后绢涡,關(guān)聯(lián)的Job對(duì)象實(shí)例會(huì)被釋放,且會(huì)被JVM GC清除遣疯。重要屬性有name雄可,group,jobClass缠犀,jobDataMap
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)//傳入自定義實(shí)現(xiàn)Job的任務(wù)類 .withIdentity("h1","group1")//定義name,group .usingJobData("count","11111")//JobDataMap實(shí)現(xiàn)了JDK的Map接口数苫,可以以Key-Value的形式存儲(chǔ)數(shù)據(jù)。 .build();
-
-
JobExecutionContext:中包含了Quartz運(yùn)行時(shí)的環(huán)境以及Job本身的詳細(xì)數(shù)據(jù)信息辨液。
當(dāng)Schedule調(diào)度執(zhí)行一個(gè)Job的時(shí)候虐急,就會(huì)將JobExecutionContext傳遞給該Job的execute()中,Job就可以通過JobExecutionContext對(duì)象獲取信息滔迈。public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobKey jobKey = jobExecutionContext.getJobDetail().getKey(); System.out.println(jobKey.getName()+"-----"+jobKey.getGroup());//獲取到j(luò)obDetail里定義的name和group JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();//拿到j(luò)obDataMap里傳入的jobDataMap數(shù)據(jù)止吁。就是這一句 .usingJobData("count","11111")。 String count = jobDataMap.getString("count");//根據(jù)key獲取value值 System.out.println(count); //可以拿到很多數(shù)據(jù)燎悍,可以拿到j(luò)obDetail敬惦,相反也可以拿到tigger里的數(shù)據(jù)。還可以拿到其他比如任務(wù)名稱等數(shù)據(jù)... }
打印數(shù)據(jù)為: h1-----group1 11111
-
Trigger谈山、SimpleTrigger俄删、CronTrigger
Trigger:rigger是Quartz的觸發(fā)器,會(huì)去通知Scheduler何時(shí)去執(zhí)行對(duì)應(yīng)Job奏路。
SimpleTrigger:SimpleTrigger可以實(shí)現(xiàn)在一個(gè)指定時(shí)間段內(nèi)執(zhí)行一次作業(yè)任務(wù)或一個(gè)時(shí)間段內(nèi)多次執(zhí)行作業(yè)任務(wù)畴椰。
下面的程序就實(shí)現(xiàn)了程序運(yùn)行5s后開始執(zhí)行Job,執(zhí)行Job 5s后結(jié)束執(zhí)行:-
CronTrigger:CronTrigger功能非常強(qiáng)大思劳,是基于日歷的作業(yè)調(diào)度迅矛,而SimpleTrigger是精準(zhǔn)指定間隔,所以相比SimpleTrigger潜叛,CroTrigger更加常用秽褒。CroTrigger是基于Cron表達(dá)式的壶硅,先了解下Cron表達(dá)式:
由7個(gè)子表達(dá)式組成字符串的,格式如下:[秒] [分] [小時(shí)] [日] [月] [周] [年]
如果不知道什么寫销斟,可通過在線生成Cron表達(dá)式的工具:http://cron.qqe2.com/ 來生成自己想要的表達(dá)式庐椒。
//寫法跟SimpleTrigger一樣,就是withSchedule傳入的觸發(fā)器不一樣和返回值不一樣蚂踊。 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來進(jìn)行定時(shí)约谈。每周一到周五上午10:30執(zhí)行定時(shí)任務(wù) .build();