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