前段時(shí)間項(xiàng)目中使用到了quartz這個(gè)調(diào)度框架,最近有時(shí)間正好可以做一總結(jié),現(xiàn)在使用的主要是兩個(gè)版本,一個(gè)就是2.0以下版本,還要一個(gè)就是2.0以上今天咱們從quartz的本地啟動(dòng)-->quartz持久化數(shù)據(jù)庫(kù)兩大方面來總結(jié)和學(xué)習(xí)quartz拗小。首先咱們先來看一下幾個(gè)概念,學(xué)習(xí)技術(shù)的基礎(chǔ)就是理論先行樱哼,所謂知其然知其所以然哀九。
首先來看一下這個(gè)圖,這個(gè)圖是我從網(wǎng)上截取的圖片搅幅,這個(gè)文章講的很好可以作為進(jìn)階來學(xué)習(xí)阅束。學(xué)習(xí)地址
我們看一下上圖:
Job:Job就是一個(gè)接口息裸,咱們想要執(zhí)任務(wù)調(diào)度就要實(shí)現(xiàn)該接口年扩,他只有一個(gè)方法需要咱們實(shí)現(xiàn)况脆,可以看下源碼笆搓,我們的任務(wù)作業(yè)就在這個(gè)方法里:
package org.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public interface Job {
void execute(JobExecutionContext var1) throws JobExecutionException;
}
Scheduler:Scheduler是咱們?nèi)蝿?wù)調(diào)度器,你就當(dāng)他是一個(gè)池子這個(gè)池子有好多個(gè)輸水管道。
Trigger:知道意思就是觸發(fā)器的意思厢漩,那這個(gè)就是咱們?nèi)蝿?wù)的觸發(fā)器炸宵,就是池子中的一個(gè)觸發(fā)引擎(輸水管道)。觸發(fā)器的話就要有一個(gè)規(guī)則促使他如何執(zhí)行拨黔,咱們這邊有主要有SimpleTrigger和CronTrigger這兩個(gè)子類麸塞。區(qū)別就是一個(gè)是簡(jiǎn)單的執(zhí)行策略,比如心跳執(zhí)行規(guī)則,而 CronTrigger 是正則表達(dá)式規(guī)則執(zhí)行程奠,咱們后面再說。
JobDetail:每個(gè)任務(wù)的具體的細(xì)節(jié)伪货,包括job名们衙,job的group蒙挑,job的監(jiān)聽信息等忆蚀。
ThreadPool:顧名思義就是線程池呀忧,我們都知道線程池的好處而账,當(dāng)然好的框架就使用最優(yōu)的性能的代碼啦笔横,使用共享線程池可以提高作業(yè)的處理能力
Calendar:quartz的特殊時(shí)間點(diǎn)集合,比如咱們需要在某個(gè)時(shí)間點(diǎn)執(zhí)行或者不執(zhí)行咐吼,就要Trigger結(jié)合Calendar使用吹缔。
以上就是一個(gè)任務(wù)的基本的需要的元素。
具體的執(zhí)行就是咱們的調(diào)度器Schedule調(diào)度咱們的一個(gè)觸發(fā)器Trigger锯茄,這個(gè)觸發(fā)器綁定這一個(gè)JobDetail作業(yè)厢塘,這個(gè)任務(wù)就根據(jù)觸發(fā)器中的執(zhí)行規(guī)則配置執(zhí)行Job中的作業(yè)就可以了。是不是很簡(jiǎn)單肌幽,當(dāng)然具體的執(zhí)行還有很多細(xì)節(jié)晚碾,但是咱們先有個(gè)大的框架。
好了我們先來看一下在內(nèi)存中創(chuàng)建一個(gè)任務(wù)喂急,先練練手咱們主要看1.8.6和2.1.7兩個(gè)版本的不同使用方法格嘁,在持久化的時(shí)候咱們使用高版本。
1.需要的依賴包:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>1.8.6</version>
</dependency>
2.創(chuàng)建我們的任務(wù)廊移,就是實(shí)現(xiàn)Job:
package com.spring.traning.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* Created by luyang.li on 17/1/9.
*/
public class SimpleQuartzJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("Simple Quertz Test!");
}
}
我把import帶著防止有的同學(xué)引錯(cuò)包糕簿,我們剛才看了源碼探入,只有一個(gè)方法需要實(shí)現(xiàn)execute:
void execute(JobExecutionContext context)throwsJobExecutionException;
這個(gè)方法就是我們需要執(zhí)行的作業(yè)任務(wù),我們的業(yè)務(wù)邏輯到時(shí)候就在這個(gè)里面實(shí)現(xiàn)啦懂诗。
3.任務(wù)有了接下來咱們綁定任務(wù)和創(chuàng)建調(diào)度器等:
3.1創(chuàng)建調(diào)度器
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
我們來看一下這個(gè)創(chuàng)建過程:StdSchedulerFactory類實(shí)現(xiàn)了SchedulerFactory工廠類蜂嗽,這個(gè)工廠類是一個(gè)接口,他的方法:getScheduler里面大有學(xué)問:咱們一路跟進(jìn)去看看:
public Scheduler getScheduler() throws SchedulerException {
if (cfg == null) {
initialize();
}
SchedulerRepository schedRep = SchedulerRepository.getInstance();
Scheduler sched = schedRep.lookup(getSchedulerName());
if (sched != null) {
if (sched.isShutdown()) {
schedRep.remove(getSchedulerName());
} else {
return sched;
}
}
sched = instantiate();
return sched;
}
首選會(huì)初始化cfg,就是咱們的配置文件响禽,要是咱們沒有添加的配置的話就使用的Quartz自己的配置徒爹,我就不貼代碼了,感興趣的同學(xué)可以深入去看看芋类。
主要在這里:
SchedulerRepository schedRep = SchedulerRepository.getInstance();
public static synchronized SchedulerRepository getInstance() {
if (inst == null) {
inst = new SchedulerRepository();
}
return inst;
}
沒有實(shí)例的話就創(chuàng)建一個(gè)實(shí)例:
private SchedulerRepository() {
schedulers = new HashMap();
}
哈哈其實(shí)他是一個(gè)Map隆嗅,那么久印證了圖里面畫的,其實(shí)咱們的任務(wù)都在JobDataMap中呢侯繁。
Scheduler sched = schedRep.lookup(getSchedulerName());
private String getSchedulerName() {
return cfg.getStringProperty(PROP_SCHED_INSTANCE_NAME,
"QuartzScheduler");
}
這個(gè)方法里是讀取quartz的配置構(gòu)造咱們的實(shí)例胖喳。在這里咱們得到的是quartz默認(rèn)的實(shí)例。好了我們得到了一個(gè)調(diào)度器了贮竟,下面我們就可以添加?xùn)|西了丽焊。
//創(chuàng)建一個(gè)作業(yè) 注冊(cè) 作業(yè)名 和 組
JobDetail jobDetail = new JobDetail("simpleQuartz", "group1", SimpleQuartzJob.class);
//任務(wù)觸發(fā)器
SimpleTrigger trigger = new SimpleTrigger("simpleQuartzTime", "group1");
創(chuàng)建作業(yè)和觸發(fā)器。并把作業(yè)綁定在觸發(fā)器上咕别,這里注意的是new JobDetail的時(shí)候第一個(gè)參數(shù)是Job的名name技健,第二個(gè)參數(shù)是job組group,第三個(gè)是咱們需要執(zhí)行的Class。Trigger咱們先使用的心跳的方式執(zhí)行:SimpleTrigger參數(shù)分別是name和group惰拱。
來看下完整的代碼:
package com.spring.traning.quartz;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
* Created by luyang.li on 17/1/9.
*/
public class SimpleQuertzApp {
public static void main(String[] args) throws SchedulerException, InterruptedException {
SimpleQuertzApp simpleQuertzApp = new SimpleQuertzApp();
simpleQuertzApp.run();
// Thread.sleep(1000000);
}
private void run() throws SchedulerException {
Date runTime = new Date();
//創(chuàng)建一個(gè)調(diào)度器
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
//創(chuàng)建一個(gè)作業(yè) 注冊(cè) 作業(yè)名 和 組
// JobDetail jobDetail = newJob(SimpleQuartzJob.class).withIdentity("simpleQuartz", "group1").build();
JobDetail jobDetail = new JobDetail("simpleQuartz", "group1", SimpleQuartzJob.class);
//任務(wù)觸發(fā)器
// Trigger trigger = newTrigger().withIdentity("simpleQuartzTime", "group1").startAt(runTime).build();
SimpleTrigger trigger = new SimpleTrigger("simpleQuartzTime", "group1");
long ctime = System.currentTimeMillis();
trigger.setStartTime(new Date(ctime));
//設(shè)置作業(yè)執(zhí)行間隔
trigger.setRepeatInterval(1000);
//設(shè)置作業(yè)執(zhí)行次數(shù)
trigger.setRepeatCount(10);
//設(shè)置作業(yè)執(zhí)行優(yōu)先級(jí)默認(rèn)為5
trigger.setPriority(10);
//把觸發(fā)器 和 作業(yè)綁定在調(diào)度器上
scheduler.scheduleJob(jobDetail, trigger);
//執(zhí)行
scheduler.start();
// try {
// Thread.sleep(65 * 1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// scheduler.shutdown();
System.out.println("運(yùn)行結(jié)束!");
}
}
執(zhí)行就可以看到心跳任務(wù)執(zhí)行了雌贱,下一節(jié)咱們看下2.1.7和持久化任務(wù)執(zhí)行以及整合Spring