Quartz.基本使用
一、定時(shí)任務(wù)
在很多情況下任務(wù)并非需要立即執(zhí)行 , 而是需要往后或定期執(zhí)行 , 這不可能人工去操作 , 所以定時(shí)任務(wù)就出現(xiàn)了 Scheduled 參數(shù) @Scheduled(fixedRate=5000): 上?次開(kāi)始執(zhí)?時(shí)間點(diǎn)之后 5 秒再執(zhí)? @Scheduled(fixedDelay=5000): 上?次執(zhí)?完畢時(shí)間點(diǎn)之后 5 秒再執(zhí)? @Scheduled(initialDelay=1000, fixedRate=5000): 第?次延遲 1 秒后執(zhí)? , 之后按 fixedRate 的規(guī)則 每5 秒執(zhí)??次 @Scheduled(cron="*/5 * * * * *"): 通過(guò) cron 表達(dá)式定義規(guī)則1、Scheduled創(chuàng)建定時(shí)任務(wù)
①、在SpringBoot的啟動(dòng)類類中加? @EnableScheduling 注解,啟?定時(shí)任務(wù)的配置?②、創(chuàng)建定時(shí)任務(wù)實(shí)現(xiàn)類
package com.mwy.code;import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;import java.time.LocalDateTime;@Component @Slf4j public class Task {@Scheduled(fixedRate = 2000)public void work() {log.warn("現(xiàn)在時(shí)間:" + LocalDateTime.now());} }測(cè)試:
?測(cè)試類測(cè)試只能執(zhí)行一次,使用死循環(huán)執(zhí)行多次
cron 表達(dá)式 cron 表達(dá)式是一個(gè)字符串 , 以 5 或者 6 個(gè)空格隔開(kāi) ( 示例中是被 5 個(gè)空格隔開(kāi) ), 字符串被切割為 6 個(gè)或者 7 個(gè)域 , 每個(gè)域都代表不同的含義 {Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek} {Year} {Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek}每個(gè)域都可以用數(shù)字表示,還可以出現(xiàn)如下特殊字符 ?
* : 表示匹配該域的任意值 , 比如 Minutes 域使用 *, 就表示每分鐘都會(huì)觸發(fā) - : 表示范圍 , 比如 Minutes 域使用 10-20, 就表示從 10 分鐘到 20 分鐘每分鐘都會(huì)觸發(fā)一次 , : 表示列出枚舉值 , 比如 Minutes 域使用 1,3. 就表示 1 分鐘和 3 分鐘都會(huì)觸發(fā)一次 / : 表示間隔時(shí)間觸發(fā) ( 開(kāi)始時(shí)間 / 時(shí)間間隔 ), 例如在 Minutes 域使用 5/10, 就表示從第 5 分鐘開(kāi)始 , 每隔 10 分鐘觸發(fā)一次 ? : 表示不指定值 , 簡(jiǎn)單理解就是忽略該字段的值 , 直接根據(jù)另一個(gè)字段的值觸發(fā)執(zhí)行 # : 表示該月第 n 個(gè)星期 x(x#n), 僅用星期域 , 如:星期: 6#3, 表示該月的第三個(gè)星期五 L : 表示最后 , 是單詞 "last" 的縮寫(最后一天或最后一個(gè)星期幾);僅出現(xiàn)在日和星期的域中 , 用在日則表 示該月的最后一天, 用在星期則表示該月的最后一個(gè)星期 , 如:星期域上的值為 5L, 則表示該月最后一個(gè)星期的 星期四, 在使用 'L' 時(shí) , 不要指定列表 ',' 或范圍 '-', 否則易導(dǎo)致出現(xiàn)意料之外的結(jié)果 W: 僅用在日的域中 , 表示距離當(dāng)月給定日期最近的工作日(周一到周五) , 是詞 "weekday" 的縮寫 例如: */10 * * * * ? 0 */5 * * * ? 0 2,22,32 * * * ? 0 0 4-8 * * ? 0 0 2 * * ? 0 0 2 1 * ? 0 * 14 * * ? 0 0/5 14,18 * * ? 0 0-5 14 * * ? 0 10,44 14 ? 3 3 0 15 10 ? * MON-FRI 0 15 10 L * ? 0 15 10 ? * 6L 2002-2005 星期里, 1 表示的是星期天, 2 表示的是星期一,以此類推, 7 表示的是星期六 ?只存在于某天或某星期中,且不能同時(shí)存在 ( 還不支持同時(shí)指定某天和星期 ) 'L' 和 'W' 字符也可以在日期字段中組合以產(chǎn)生 'LW' ,這轉(zhuǎn)換為 “ 最后一個(gè)工作日 ” 法定字符以及月份和星期的名稱不區(qū)分大小寫,如 MON 與 mon 相同注意:日和星期不能同時(shí)出現(xiàn)
cron表達(dá)式的缺點(diǎn):
1.任務(wù)在內(nèi)存中執(zhí)行,一旦系統(tǒng)斷開(kāi),任務(wù)就消失了,任務(wù)數(shù)據(jù)也就沒(méi)有了
2.不能實(shí)現(xiàn)共享,存在于本機(jī)內(nèi)存中
二、Quartz創(chuàng)建定時(shí)任務(wù)
任務(wù)存儲(chǔ)方式: (1)內(nèi)存方式(RAMJobStore) :將任務(wù)臨時(shí)存儲(chǔ)到內(nèi)存中,僅支持單項(xiàng)目部署,項(xiàng)目重啟后任務(wù)會(huì)失效,不 支持由調(diào)度器控制任務(wù)漂移,不建議使用。 (2)數(shù)據(jù)庫(kù)方式(JDBCJobStore): ? Quartz提供了多種數(shù)據(jù)庫(kù)的所需表結(jié)構(gòu)腳本,它內(nèi)部通過(guò) DataSource 來(lái) 操作數(shù)據(jù)支持分布式方式部署、支持任務(wù)漂移,項(xiàng)目重啟后任務(wù)不會(huì)丟失,直到任務(wù)執(zhí)行完成后才會(huì)被從數(shù)據(jù)庫(kù)內(nèi)清除。 SchedulerFactory 調(diào)度器工廠: SchedulerFactory factory = new StdSchedulerFactory(); Scheduler 調(diào)度器: Scheduler scheduler = factory.getScheduler(); 用于與調(diào)度程序交互的主程序接口 . Scheduler 維護(hù)了一個(gè) JobDetails 和 Triggers 的注冊(cè)表。 一旦在 Scheduler 注冊(cè)過(guò)了,當(dāng)定時(shí)任務(wù)觸發(fā)時(shí)間一到,調(diào)度程序就會(huì)負(fù)責(zé)執(zhí)行預(yù)先定義的 Job調(diào)度程序創(chuàng)建之后,處于“ 待機(jī) ” 狀態(tài),必須調(diào)用 scheduler 的 start() 方法啟用調(diào)度程序 可以使用 shutdown() 方法關(guān)閉調(diào)度程序,使用 isShutdown() 方法判斷該調(diào)度程序是否已經(jīng)處于關(guān)閉狀態(tài) 通過(guò) Scheduler.scheduleJob(…) 方法將任務(wù)納入調(diào)度程序中,當(dāng)任務(wù)觸發(fā)時(shí)間到了的時(shí)候,該任務(wù)將被執(zhí)行1、導(dǎo)入pom依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId> </dependency>2、內(nèi)存方式:
①、實(shí)例化調(diào)度器工廠:
StdSchedulerFactory:可讀取配置文件
SchedulerFactory SchedulerFactory=new StdSchedulerFactory();②、得到調(diào)度器
Scheduler?維護(hù)了一個(gè)?JobDetails(任務(wù))?和?Triggers(觸發(fā)時(shí)間)??的注冊(cè)表
Scheduler scheduler = SchedulerFactory.getScheduler();③、創(chuàng)建一個(gè)任務(wù)類MyJob,實(shí)現(xiàn)job接口成為一個(gè)任務(wù),實(shí)現(xiàn)方法
任務(wù)是一個(gè)實(shí)現(xiàn) org.quartz.Job 接口的類,任務(wù)類必須含有空構(gòu)造器 當(dāng)關(guān)聯(lián)這個(gè)任務(wù)實(shí)例的觸發(fā)器表明的執(zhí)行時(shí)間到了的時(shí)候,調(diào)度程序 Scheduler 會(huì)調(diào)用這個(gè)方法來(lái)執(zhí)行 任務(wù),任務(wù)內(nèi)容就可以在這個(gè)方法中執(zhí)行 JobDataMap 提供了一種 “ 初始化成員屬性數(shù)據(jù)的機(jī)制 ”, 在實(shí)現(xiàn)該 Job 接口的時(shí)候可以取到需要的數(shù)據(jù) JobDetail jobDetail = newJob(MyJob.class).withDescription("教員布置作業(yè)").withIdentity("敲代碼", "Quartz的基本使用").usingJobData("name", "mwy").build();context.getJobDetail().getKey() = name + group ?
④、創(chuàng)建觸發(fā)器
觸發(fā)器使用 TriggerBuilder 來(lái)實(shí)例化,有一個(gè) TriggerKey 關(guān)聯(lián),在一個(gè) Scheduler 中必須是唯一的。 多個(gè)觸發(fā)器可以指向同一個(gè)工作,但一個(gè)觸發(fā)器只能指向一個(gè)工作。 觸發(fā)器可以傳送數(shù)據(jù)給 job ,通過(guò)將數(shù)據(jù)放進(jìn)觸發(fā)器的 JobDataMap 。 觸發(fā)器常用屬性 觸發(fā)器也有很多屬性,這些屬性都是在使用 TriggerBuilder 定義觸發(fā)器時(shí)設(shè)置的。 TriggerKey ,唯一標(biāo)識(shí),在一個(gè) Scheduler 中必須是唯一的 startTime ,開(kāi)始時(shí)間,通常使用 startAt(java.util.Date) endTime ,結(jié)束時(shí)間,設(shè)置了結(jié)束時(shí)間則在這之后,不再觸發(fā) Trigger trigger = TriggerBuilder.newTrigger().withDescription("寫作業(yè)觸發(fā)器").withIdentity("敲代碼", "Quartz的基本使用").startAt(new Date()).build(); 如果沒(méi)有使用 withIdentity(..) 會(huì)自動(dòng)生成一個(gè)觸發(fā)器名稱。 觸發(fā)器的優(yōu)先級(jí) 有時(shí)候,會(huì)安排很多任務(wù),但是 Quartz 并沒(méi)有更多的資源去處理它。 這種情況下,必須需要很好地控制哪個(gè)任務(wù)先執(zhí)行。這時(shí)候可以設(shè)置 priority 屬性(使用方法 withPriority(int) )來(lái)控制觸發(fā)器的優(yōu)先級(jí)。 優(yōu)先級(jí)只有觸發(fā)器出發(fā)時(shí)間一樣的時(shí)候才有意義。 當(dāng)一個(gè)任務(wù)請(qǐng)求恢復(fù)執(zhí)行時(shí),它的優(yōu)先級(jí)和原始優(yōu)先級(jí)是一樣的。 常見(jiàn)觸發(fā)器 TriggerBuilder 用于創(chuàng)建 Trigger ,如果沒(méi)有調(diào)用 withSchedule(..) 方法,會(huì)使用默認(rèn)的 schedule 。 簡(jiǎn)單觸發(fā)器 SimpleTrigger SimpleTrigger 包含幾個(gè)特點(diǎn):開(kāi)始時(shí)間、結(jié)束時(shí)間、重復(fù)次數(shù)以及重復(fù)執(zhí)行的時(shí)間間隔 基于 Cron 表達(dá)式的觸發(fā)器 CronTrigger Trigger trigger = TriggerBuilder . newTrigger () . withIdentity ( "test" , "test" ) . withDescription ( " 測(cè)試的觸發(fā)器 " ) . withSchedule ( CronScheduleBuilder . cronSchedule ( "2 * * * * *" )) . build ();⑤、將觸發(fā)器和任務(wù)綁定到調(diào)度器
scheduler.scheduleJob(jobDetail,trigger);⑥、啟動(dòng)調(diào)度器
scheduler.start();⑦、測(cè)試結(jié)果
3、?job和jobDetail的區(qū)別
job是任務(wù)模板,jobDetail是實(shí)例
①、創(chuàng)建兩個(gè)jobDetail實(shí)例?,usingJobData不同
?②、在任務(wù)模板中獲取到name屬性(MyJob)
package com.mwy.code; import lombok.extern.slf4j.Slf4j; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; @Slf4j public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {Object name= context.getJobDetail().getJobDataMap().get("name");log.warn(name+"寫作業(yè)");} }運(yùn)行結(jié)果:
?如果想要放入很多數(shù)據(jù),可以用JobDataMap集合?
③、設(shè)置時(shí)間以及執(zhí)行次數(shù)
SimpleTrigger 特點(diǎn):開(kāi)始時(shí)間、結(jié)束時(shí)間、重復(fù)次數(shù)以及重復(fù)執(zhí)行的時(shí)間間隔。
Trigger trigger = TriggerBuilder.newTrigger().withDescription("寫作業(yè)觸發(fā)器").withIdentity("敲代碼", "Quartz的基本使用").startAt(new Date()).withSchedule(simpleSchedule().withIntervalInSeconds(1)//時(shí)間間隔.withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY) //SimpleTrigger.REPEAT_INDEFINITELY).build();Cron生成器 :? ?http://cron.ciding.cc/
?基于?Cron?表達(dá)式的觸發(fā)器?CronTrigger
Trigger trigger = TriggerBuilder.newTrigger().withDescription("寫作業(yè)觸發(fā)器").withIdentity("敲代碼", "Quartz的基本使用").startAt(new Date()).withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?")).build();總結(jié)
以上是生活随笔為你收集整理的Quartz.基本使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MySQL有什么推荐的学习书籍?
- 下一篇: 水果店开在哪位置最好,水果店应开到什么位