java基礎(chǔ)-day61-Quartz

Quartz


1.1 簡介

Quartzhttp://www.quartz-scheduler.org/

是一個定時任務(wù)調(diào)度框架。比如你遇到這樣的問題:

  • 想在30分鐘后硕淑,查看訂單是否支付弟灼,未支付則取消訂單
  • 想在每月29號族跛,信用卡自動還款
  • ...
  • 想定時在某個時間鞍爱,去做某件事(任務(wù))初肉。

Quartz是要做定時任務(wù)的調(diào)度呻惕,設(shè)置好觸發(fā)時間規(guī)則荆责,以及相應(yīng)的任務(wù)(Job)即可。

二亚脆、Quartz使用


2.1 導(dǎo)入依賴

<dependencies>
    <!--Quartz任務(wù)調(diào)度-->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.2</version>
    </dependency>
</dependencies>

2.2 定義Job

/**
 * 工作類的具體實現(xiàn)做院,即需要定時執(zhí)行的“某件事”
 * */
public class MyJob implements Job {
    //執(zhí)行
    public void execute(JobExecutionContext context) throws JobExecutionException {
         //創(chuàng)建工作詳情
        JobDetail jobDetail=context.getJobDetail();
        //獲取工作的名稱
        String jobName = jobDetail.getKey().getName();//任務(wù)名
        String jobGroup = jobDetail.getKey().getGroup();//任務(wù)group
        System.out.println("job執(zhí)行,job:"+jobName+" group:"+jobGroup);
        System.out.println(new Date());
    }
}

2.3 API測試

package com.qf;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.GregorianCalendar;

public class TestQuartz {

    public static void main(String[] args) throws Exception{
        //創(chuàng)建scheduler濒持,調(diào)度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //定義一個Trigger,觸發(fā)條件類
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1") //定義name/group
                .startNow()//設(shè)置開始時間键耕,一旦加入scheduler,表示立即生效柑营,即開始計時
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(2) //每隔2秒執(zhí)行一次
                        //.repeatForever()) //一直執(zhí)行屈雄,直到結(jié)束時間
                        .withRepeatCount(3))//設(shè)置執(zhí)行次數(shù)
                //設(shè)置結(jié)束時間(注:月份默認(rèn)從0開始)
                .endAt(new GregorianCalendar(2020,5,27,17,30,10).getTime())
                .build();
        //定義一個JobDetail
        JobDetail job = JobBuilder.newJob(MyJob.class)
                .withIdentity("job1","group1") //定義name/group
                .build();
        //調(diào)度器 中加入 任務(wù)和觸發(fā)器
        scheduler.scheduleJob(job, trigger);
        //啟動任務(wù)調(diào)度
        scheduler.start();
    }
}

2.4 默認(rèn)配置

# 名為:quartz.properties,放置在classpath下官套,如果沒有此配置則按默認(rèn)配置啟動
# 指定調(diào)度器名稱酒奶,非實現(xiàn)類
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
# 指定線程池實現(xiàn)類
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# 線程池線程數(shù)量
org.quartz.threadPool.threadCount = 10 
# 優(yōu)先級,默認(rèn)5
org.quartz.threadPool.threadPriority = 5
# 非持久化job
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

2.5 核心類說明

Scheduler:調(diào)度器奶赔。所有的調(diào)度都是由它控制讥蟆,是Quartz的大腦,所有任務(wù)都是由它來管理

Job:任務(wù)纺阔,想定時執(zhí)行的事情(定義業(yè)務(wù)邏輯)

JobDetail:基于Job瘸彤,進(jìn)一步包裝。其中關(guān)聯(lián)一個Job笛钝,并為Job指定更詳細(xì)的屬性质况,比如標(biāo)識等

Trigger:觸發(fā)器〔C遥可以指定給某個任務(wù)结榄,指定任務(wù)的觸發(fā)機(jī)制。

三囤捻、Trigger


3.1 SimpleTrigger

以一定的時間間隔(單位是毫秒)執(zhí)行的任務(wù)臼朗。

  • 指定起始和截止時間(時間段)
  • 指定時間間隔、執(zhí)行次數(shù)

示例:

SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                          .withIntervalInSeconds(1) //每秒執(zhí)行一次
                          .repeatForever())// 不限執(zhí)行次數(shù)
                .endAt(new GregorianCalendar(2020, 4, 7, 2, 24, 0).getTime())
                .build();
SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                          .withIntervalInMinutes(3) // 每3分鐘執(zhí)行一次
                          .withRepeatCount(3)) // 執(zhí)行次數(shù)不超過3次
                .endAt(new GregorianCalendar(2020, 4, 7, 2, 24, 0).getTime()) 
                .build();

3.2 CronTrigger 【重點

適合于更復(fù)雜的任務(wù)蝎土,它支持類型于Linux Cron的語法(并且更強(qiáng)大)视哑。

  • 指定Cron表達(dá)式即可

示例:

// 每天10:00-12:00,每隔2秒鐘執(zhí)行一次
CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger2", "group2")
                .withSchedule(CronScheduleBuilder.cronSchedule("*/2 * 10-12 * * ?"))
                .build(); 
3.2.1 Cron表達(dá)式組成

表達(dá)式組成:"秒 分 時 日 月 星期幾 [年]" 誊涯,其中"年" 是可選的挡毅,一般不指定。

  • 如:"10 20 18 3 5 ?"代表"5月3日18點20分10秒暴构,星期幾不確定 "
位置 時間域 允許值 特殊值
1 0-59 , - * /
2 分鐘 0-59 , - * /
3 小時 0-23 , - * /
4 日期 1-31 , - * ? / L W
5 月份 1-12 , - * /
6 星期 1-7 , - * ? / L #
7 年份(可選) , - * /
3.2.2 Cron表達(dá)式符號

表達(dá)式中可使用的特殊符號的含義如下

符號 語義
星號(*) 可用在所有字段中跪呈,表示對應(yīng)時間域的每一個時刻段磨,例如, 在分鐘字段時耗绿,表示“每分鐘”
問號(?) 該字符只在日期和星期字段中使用苹支,它通常指定為“不確定值”
減號(-) 表達(dá)一個范圍,如在小時字段中使用“10-12”误阻,則表示從10到12點债蜜,即10,11,12
逗號(,) 表達(dá)一個列表值,如在星期字段中使用“MON,WED,FRI”堕绩,則表示星期一策幼,星期三和星期五
斜杠(/) x/y表達(dá)一個等步長序列,x為起始值奴紧,y為增量步長值特姐。如在分鐘字段中使用0/15,則表示為0,15,30和45秒黍氮,而5/15在分鐘字段 中表示5,20,35,50
井號(#) 該字符只用在星期字段中唐含,"4#2"代表第二個星期3,“5#4”代表第4個星期四
L 該字符只在日期和星期字段中使用沫浆,代表“Last”的意思捷枯,但它在兩個字段中意思不同。
如果L用在星期字段里专执,則表示星期六淮捆,等同于7
L出現(xiàn)在星期字段里,而且在前面有一個數(shù)值x本股,則表示“這個月的最后一個周x”攀痊,例如,6L表示該月的最后星期五
L在日期字段中拄显,表示這個月份的最后一天苟径,如一月的31號,非閏年二月的28號
W 該字符只能出現(xiàn)在日期字段里躬审,是對前導(dǎo)日期的修飾棘街,表示離該日期最近的工作日
例如15W表示離該月15號最近的工作日,如果該月15號是星期六承边,則匹配14號星期五遭殉;如果15日是星期日,則匹配16號星期一炒刁;如果15號 是星期二恩沽,那結(jié)果就是15號星期二;但必須注意關(guān)聯(lián)的匹配日期不能夠跨月
LW組合 在日期字段可以組合使用LW翔始,它的意思是當(dāng)月的最后一個工作日
3.2.3 Cron表達(dá)式示例

演示實例

表示式 說明
0 0 12 * * ? 每天12點運行
0 15 10 * * ? 每天10:15運行
0 15 10 * * ? 2008 在2008年的每天10:15運行
0 * 14 * * ? 每天14點到15點之間每分鐘運行一次罗心,開始于14:00,結(jié)束于14:59城瞎。
0 0/5 14 * * ? 每天14點到15點每5分鐘運行一次渤闷,開始于14:00,結(jié)束于14:55脖镀。
0 0/5 14,18 * * ? 每天14點到15點每5分鐘運行一次飒箭,此外每天18點到19點每5鐘也運行一次。
0 0-5 14 * * ? 每天14:00點到14:05蜒灰,每分鐘運行一次弦蹂。
0 0-5/2 14 * * ? 每天14:00點到14:05,每2分鐘運行一次强窖。
0 10,44 14 ? 3 4 3月每周三的14:10分和14:44分凸椿,各運行一次。
0 15 10 ? * 2-6 每周一翅溺,二脑漫,三,四咙崎,五的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分運行伊滋。

四碳却、Spring整合Quartz 【重點

4.1 依賴

<dependencies>
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.2.6.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.2.6.RELEASE</version>
    </dependency>
</dependencies>

4.2 定義Job

定義一個Job類

public class MyJob implements Job {
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.err.println("job 執(zhí)行"+new Date());
    }
}

4.3 配置applicationContext.xml

調(diào)度器 SchedulerFactoryBean

觸發(fā)器 CronTriggerFactoryBean

JobDetail JobDetailFactoryBean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        Spring整合Quartz進(jìn)行配置遵循下面的步驟:
        1:定義工作任務(wù)的Job
        2:定義觸發(fā)器Trigger,并將觸發(fā)器與工作任務(wù)綁定
        3:定義調(diào)度器新啼,并將Trigger注冊到Scheduler
     -->

    <!-- 1:定義任務(wù)的bean 追城,這里使用JobDetailFactoryBean,也可以使用MethodInvokingJobDetailFactoryBean ,配置類似-->
    <bean name="lxJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <!-- 指定job的名稱 -->
        <property name="name" value="job1"/>
        <!-- 指定job的分組 -->
        <property name="group" value="job_group1"/>
        <!-- 指定具體的job類 -->
        <property name="jobClass" value="com.qf.quartz.MyJob"/>
    </bean>

    <!-- 2:定義觸發(fā)器的bean燥撞,定義一個Cron的Trigger座柱,一個觸發(fā)器只能和一個任務(wù)進(jìn)行綁定 -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!-- 指定Trigger的名稱 -->
        <property name="name" value="trigger1"/>
        <!-- 指定Trigger的名稱 -->
        <property name="group" value="trigger_group1"/>
        <!-- 指定Tirgger綁定的JobDetail -->
        <property name="jobDetail" ref="lxJob"/>
        <!-- 指定Cron 的表達(dá)式 ,當(dāng)前是每隔5s運行一次 -->
        <property name="cronExpression" value="*/5 * * * * ?" />
    </bean>

    <!-- 3.定義調(diào)度器物舒,并將Trigger注冊到調(diào)度器中 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="cronTrigger"/>
            </list>
        </property>
        <!-- 添加 quartz 配置色洞,如下兩種方式均可 -->
        <!--<property name="configLocation" value="classpath:quartz.properties"></property>-->
        <property name="quartzProperties">
            <value>
                # 指定調(diào)度器名稱,實際類型為:QuartzScheduler
                org.quartz.scheduler.instanceName = MyScheduler
                # 指定連接池
                org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
                # 連接池線程數(shù)量
                org.quartz.threadPool.threadCount = 11
                # 優(yōu)先級
                org.quartz.threadPool.threadPriority = 5
                # 不持久化job
                org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
            </value>
        </property>
    </bean>
</beans>

4.4 操作

4.4.1 啟動任務(wù)

工廠啟動冠胯,調(diào)度器啟動火诸,任務(wù)調(diào)度開始

public static void main(String[] args) throws InterruptedException, SchedulerException {    
    // 工廠啟動,任務(wù)啟動荠察,工廠關(guān)閉置蜀,任務(wù)停止
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
4.4.2 任務(wù)操作
4.4.2.1 刪除任務(wù)
public static void main(String[] args) throws InterruptedException, SchedulerException {        
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    System.out.println("=============");
    StdScheduler scheduler = (StdScheduler) context.getBean("scheduler");
    System.out.println(scheduler.getClass());
    Thread.sleep(3000);
    // 刪除Job
    scheduler.deleteJob(JobKey.jobKey("job1","job_group1"));
}
4.4.2.2 暫停奈搜、恢復(fù)
public static void main(String[] args) throws InterruptedException, SchedulerException {        
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    System.out.println("=============");
    StdScheduler scheduler = (StdScheduler) context.getBean("scheduler");
    System.out.println(scheduler.getClass());
    Thread.sleep(3000);
    // 暫停,恢復(fù)工作
    scheduler.pauseJob(JobKey.jobKey("job1","job_group1"));// 暫停工作
    Thread.sleep(3000);
    scheduler.resumeJob(JobKey.jobKey("job1","job_group1"));// 恢復(fù)工作
}
4.4.2.3 批量操作
public static void main(String[] args) throws InterruptedException, SchedulerException {        
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    System.out.println("=============");
    StdScheduler scheduler = (StdScheduler) context.getBean("scheduler");
    System.out.println(scheduler.getClass());
    Thread.sleep(3000);
    GroupMatcher<JobKey> group1 = GroupMatcher.groupEquals("job_group1");
    scheduler.pauseJobs(group1); // 暫停組中所有工作
    Thread.sleep(2000);
    scheduler.resumeJobs(group1); // 恢復(fù)組中所有工作 
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盯荤,一起剝皮案震驚了整個濱河市馋吗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秋秤,老刑警劉巖宏粤,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異灼卢,居然都是意外死亡绍哎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門鞋真,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崇堰,“玉大人,你說我怎么就攤上這事灿巧「习溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵抠藕,是天一觀的道長饿肺。 經(jīng)常有香客問我,道長盾似,這世上最難降的妖魔是什么敬辣? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮零院,結(jié)果婚禮上溉跃,老公的妹妹穿的比我還像新娘。我一直安慰自己告抄,他們只是感情好撰茎,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著打洼,像睡著了一般龄糊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上募疮,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天炫惩,我揣著相機(jī)與錄音,去河邊找鬼阿浓。 笑死他嚷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筋蓖,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼卸耘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扭勉?” 一聲冷哼從身側(cè)響起鹊奖,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤苛聘,失蹤者是張志新(化名)和其女友劉穎涂炎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體设哗,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡唱捣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了网梢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片震缭。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖战虏,靈堂內(nèi)的尸體忽然破棺而出拣宰,到底是詐尸還是另有隱情,我是刑警寧澤烦感,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布巡社,位于F島的核電站,受9級特大地震影響手趣,放射性物質(zhì)發(fā)生泄漏晌该。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一绿渣、第九天 我趴在偏房一處隱蔽的房頂上張望朝群。 院中可真熱鬧,春花似錦中符、人聲如沸姜胖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽右莱。三九已至,卻和暖如春吧凉,著一層夾襖步出監(jiān)牢的瞬間隧出,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工阀捅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留胀瞪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像凄诞,于是被迫代替她去往敵國和親圆雁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容