Quart的入門學習

一、Quartz可以用來做什麼

        Quartz是一個強大任務調度框架,我工作時候會在這些情況下使用到quartz框架,當然還有很多的應用場景,在這裏只列舉2個實際用到的

  • 用緩存的時候,每天十二點定時對內存中的全量數據進行一次更新。
  • 人事系統會在每天早晨8點給有待辦的人員自動發送Email提醒

        在我們實際的項目中,當Job過多的時候,肯定不能人工去操作,這時候就需要一個任務調度框架,幫我們自動去執行這些程序。那麼該如何實現這個功能呢?

   (1)首先我們需要定義實現一個定時功能的接口,我們可以稱之爲Task(或Job),如定時發送郵件的task(Job),重啓機器的task(Job),優惠券到期發送短信提醒的task(Job),實現接口如下: 

è¿éåå¾çæè¿°

     

     (2)有了任務之後,還需要一個能夠實現觸發任務去執行的觸發器,觸發器Trigger最基本的功能是指定Job的執行時間,執行間隔,運行次數等。  

è¿éåå¾çæè¿°

 (3)有了Job和Trigger後,怎麼樣將兩者結合起來呢?即怎樣指定Trigger去執行指定的Job呢?這時需要一個Schedule,來負責這個功能的實現。 

 

上面三個部分就是Quartz的基本組成部分:

  • 調度器:Scheduler
  • 任務:JobDetail
  • 觸發器:Trigger,包括SimpleTrigger和CronTrigger

二、使用Quartz之前的準備

1.建立一個Maven項目

2.引入quartz的依賴 

     使用quartz,我們僅僅需要在maven的pom文件中添加依賴即可。我使用的是現在最新的一個版本2.3.0,大家可以在maven的倉庫獲取到最新的版本依賴,地址:http://mvnrepository.com/artifact/org.quartz-scheduler/quartz

   但然也可以使用這個2.3.0的依賴,下面的例子都是使用此依賴並實現了效果。

<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

三、編寫第一個Quartz任務案例 - 每隔2秒鐘打印一次HelloQuartz

1.創建一個類 HelloJob.java,這個類是編寫我們的具體要實現任務(打印Hello Quartz)

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;
public class HelloJob implements Job{
  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //打印當前的執行時間 例如 2019-09-06 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("現在的時間是:"+ sf.format(date));
        //具體的業務邏輯
        System.out.println("Hello Quartz");
    }
}

 2.創建一個類HelloScheduler.java,這個是具體觸發我們的任務

public class HelloScheduler {
    public static void main(String[] args) throws SchedulerException {
        //創建一個jobDetail的實例,將該實例與HelloJob Class綁定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
        //創建一個Trigger觸發器的實例,定義該job立即執行,並且每2秒執行一次,一直執行
        SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
        //創建schedule實例
        StdSchedulerFactory factory = new StdSchedulerFactory();
        Scheduler scheduler = factory.getScheduler();
        scheduler.start();
        scheduler.scheduleJob(jobDetail,trigger);

    }
}

3、運行程序,可以看見如下效果,表明任務執行成功了

  四、第二個案例 -  每日的9點40分觸發任務打印HelloQuartz

        與上一個的簡單案例的區別在於,SimpleTrigger/CronTrigger. 簡單的定時任務,可以採用SimpleTrigger,複雜的任務一般採用CronTrigger.cronTrigger不僅可以設定單的觸發時間表,更可以設定非常複雜的觸發時間表。 CronTrigger 是基於 Unix類似於 cron 表達式,如果對cron表達式比較熟悉,那麼學習起來經非常簡單. 即使對cron表達式不熟悉,花一會兒的功夫也可以學會。(在工作中我們直接使用網上的在線生成表達式即可又快又準確)生成地址:http://cron.qqe2.com/

先上代碼,然後介紹一下cron表達式生成規則。

1.編寫任務類 HelloJob.java,具體情況編寫具體內容,如生成報表,發送郵件

public class HelloJob implements Job{
 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //打印當前的執行時間 例如 2017-11-22 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("現在的時間是:"+ sf.format(date));
        //具體的業務邏輯
        System.out.println("開始生成任務報表 或 開始發送郵件");
    }
}

 2.編寫任務觸發類  CronScheduler.java

public class CronScheduler {
     public static void main(String[] args) throws SchedulerException, InterruptedException {
        //jobDetail
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("cronJob").build();
        //cronTrigger
        //每日的9點40觸發任務
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("cronTrigger").withSchedule(CronScheduleBuilder.cronSchedule("0 40 9 * * ? ")).build();
        //1.每日10點15分觸發      0 15 10 ?* *
        //2.每天下午的2點到2點59分(正點開始,隔5分觸發)       0 0/5 14 * * ?
        //3.從週一到週五每天的上午10點15觸發      0 15 10 ? MON-FRI
        //4.每月的第三週的星期五上午10點15觸發     0 15 10 ? * 6#3
        //5.2016到2017年每月最後一週的星期五的10點15分觸發   0 15 10 ? * 6L 2016-2017
        //Scheduler實例
        StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = stdSchedulerFactory.getScheduler();
        scheduler.start();
        scheduler.scheduleJob(jobDetail,cronTrigger);
    }
}

3.觸發的效果

 

五、cron表達式編寫規則

 1. Quartz Cron 表達式支持7個域 ,分別是秒/分/時/日/月/周/年.期中年是非必須項.如下圖

名稱 是否必須 允許值 特殊字符
0-59 , - * /
0-59 , - * /
0-23 , - * /
1-31 , - * ? / L W C
1-12 或 JAN-DEC , - * /
1-7 或 SUN-SAT , - * ? / L C #
空 或 1970-2099 , - * /

注意在cron表達式中不區分大小寫.

星號(*):可用在所有字段中,表示對應時間域的每一個時刻,例如, 在分鐘字段時,表示“每分鐘”;

問號(?):該字符只在日期和星期字段中使用,它通常指定爲“無意義的值”,相當於點位符;

減號(-):表達一個範圍,如在小時字段中使用“10-12”,則表示從10到12點,即10,11,12;

逗號(,):表達一個列表值,如在星期字段中使用“MON,WED,FRI”,則表示星期一,星期三和星期五;

斜槓(/):x/y表達一個等步長序列,x爲起始值,y爲增量步長值。如在分鐘字段中使用0/15,則表示爲0,15,30和45秒,而5/15在分鐘字段中表示5,20,35,50,你也可以使用*/y,它等同於0/y;

L:該字符只在日期和星期字段中使用,代表“Last”的意思,但它在兩個字段中意思不同。L在日期字段中,表示這個月份的最後一天,如一月的31號,非閏年二月的28號;如果L用在星期中,則表示星期六,等同於7。但是,如果L出現在星期字段裏,而且在前面有一個數值X,則表示“這個月的最後X天”,例如,6L表示該月的最後星期五;

W:該字符只能出現在日期字段裏,是對前導日期的修飾,表示離該日期最近的工作日。例如15W表示離該月15號最近的工作日,如果該月15號是星期六,則匹配14號星期五;如果15日是星期日,則匹配16號星期一;如果15號是星期二,那結果就是15號星期二。但必須注意關聯的匹配日期不能夠跨月,如你指定1W,如果1號是星期六,結果匹配的是3號星期一,而非上個月最後的那天。W字符串只能指定單一日期,而不能指定日期範圍;

LW組合:在日期字段可以組合使用LW,它的意思是當月的最後一個工作日;

井號(#):該字符只能在星期字段中使用,表示當月某個工作日。如6#3表示當月的第三個星期五(6表示星期五,#3表示當前的第三個),而4#5表示當月的第五個星期三,假設當月沒有第五個星期三,忽略不觸發;

C:該字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是計劃所關聯的日期,如果日期沒有被關聯,則相當於日曆中所有日期。例如5C在日期字段中就相當於日曆5日以後的第一天。1C在星期字段中相當於星期日後的第一天。

Cron表達式對特殊字符的大小寫不敏感,對代表星期的縮寫英文大小寫也不敏感。

2.官方的一些案例

表示式 說明
0 0 12 * * ? 每天12點運行
0 15 10 ? * * 每天10:15運行
0 15 10 * * ? 每天10:15運行
0 15 10 * * ? * 每天10:15運行
0 15 10 * * ? 2008 在2008年的每天10:15運行
0 * 14 * * ? 每天14點到15點之間每分鐘運行一次,開始於14:00,結束於14:59。
0 0/5 14 * * ? 每天14點到15點每5分鐘運行一次,開始於14:00,結束於14:55。
0 0/5 14,18 * * ? 每天14點到15點每5分鐘運行一次,此外每天18點到19點每5鍾也運行一次。
0 0-5 14 * * ? 每天14:00點到14:05,每分鐘運行一次。
0 10,44 14 ? 3 WED 3月每週三的14:10分到14:44,每分鐘運行一次。
0 15 10 ? * MON-FRI 每週一,二,三,四,五的10:15分運行。
0 15 10 15 * ? 每月15日10:15分運行。
0 15 10 L * ? 每月最後一天10:15分運行。
0 15 10 ? * 6L 每月最後一個星期五10:15分運行。
0 15 10 ? * 6L 2007-2009 在2007,2008,2009年每個月的最後一個星期五的10:15分運行。
0 15 10 ? * 6#3 每月第三個星期五的10:15分運行。

以上就可以實現大部分的業務的需求了,想要進一步學習可以到https://www.cnblogs.com/zhanghaoliang/p/7886110.html對Quartz的API進一步學習。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章