Quartz初探
目錄
Quartz執行環境
- Quartz可以執行嵌入在另一個獨立式應用程式
- Quartz可以在應用程式伺服器(或servlet容器)內被例項化,並且參與事務
- Quartz可以作為一個獨立的程式執行(其自己的java虛擬機器內),可以通過RMI使用
- Quartz可以被例項化,作為獨立的專案叢集(負載平衡和故障轉移功能),用於作業的排程
Quartz設計模式
- Builder模式
- Factory模式
- 元件模式
- 鏈式模式
Quartz學習的核心概念
- 任務job:想實現的任務類,每一個job必須實現org.quartz.job介面,且只需要實現介面定義的execute()方法.
- 觸發器Trigger:執行任務的觸發器,比如你每天想定時3點傳送一份郵件,Trigger將會設定3點進行執行該任務。Trigger主要包含兩種SimpleTrigger和CronTrigger兩種.
- 排程器Scheduler:為任務的排程器,它會將任務job及trigger整合起來,負責基於Trigger設定的時間來執行Job.
Quartz的幾個常用API
Scheduler用於與排程程式互動的主程式介面
Scheduler排程程式-任務計劃執行表,只有安排進執行計劃的任務job(通過scheduler.schdeuleJob方法安排進執行計劃),當它預先定義的執行時間到了的時候(任務觸發trigger)
Job我們預先定義的希望在未來時間能被排程程式執行的任務類,我們可以自定義。
JobDetail使用JobDetail來定義定時任務的例項,jobDetail例項是通過jobBuilder類建立的
JobDataMap可以包含不限量的(序列化的)資料物件,在job例項執行的時候,可以使用其中的資料;JobDataMap是Java Map介面的一個實現,額外增加了一些便於存取基本型別的資料方法
Trigger觸發器,Trigger物件是用來觸發執行Job的。當排程一個job時,我們例項一個觸發器然後調整它的屬性來滿足job執行的條件。表明任務在什麼時候會執行。定義了一個已經被安排的任務將會在什麼時候執行的時間條件,比如每2秒執行一次。
JobBuilder:用於宣告一個任務例項,也可以定義關於該任務的詳情比如任務名、組名等,這個宣告的例項將會作為一個實際執行的任務。
TriggerBuilder觸發器建立器,使用者建立觸發器trigger例項
JobListener、TriggerListener、SchedulerListener監聽器,用於對元件的監聽。
入門案例
1. 建立Maven專案,在pom中新增Quartz的依賴包
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
2.建立一個HelloJob類實現Job介面並重寫裡面的execute方法
package quartz.job;
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 {
//輸出當前時間
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
System.out.println("正在進行資料庫的備份工作,備份資料庫的時間是:" + dateString);
}
}
3. 建立HelloScheduler的主類
package quartz.main;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import quartz.job.HelloJob;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//1: 排程器(Schduler),從工廠中獲取排程的例項(預設:例項化new StdSchdulerFactory())
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2: 任務例項(JobDetail)
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//載入任務類,與HelloJob(實現Job介面)完成繫結
.withIdentity("job1","group1")//引數1: 任務的名稱(唯一例項); 引數2:任務組的名稱
.build();
//3: 觸發器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") //引數1: 觸發器的名稱(唯一例項); 引數2: 觸發器組的名稱
.startNow()//馬上啟動這個觸發器
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).withRepeatCount(5))
.build();
//讓排程器關聯任務和觸發器,讓任務按照觸發器定義的條件執行任務
scheduler.scheduleJob(jobDetail, trigger);
//啟動
scheduler.start();
}
}
Job和JobDetail介紹
- job:工作任務排程的介面,任務類需要實現該介面。該介面中定義execute方法,類似JDK提供的TImeTask類的run方法。在裡面編寫任務執行的業務邏輯
- job例項在Quartz的生命週期:每次排程器執行job時,它在呼叫execure方法前會建立一個新的job例項,當呼叫完成後,關聯的job物件例項會被釋放,釋放的例項會被垃圾回收機制回收。
- jobDetail:jobDetail為job提供了許多設定屬性,以及jobDetaMap成員變數屬性,它用來儲存特定的job例項的狀態資訊,排程器需要藉助jobDetail物件來新增job例項。
- jobDetail重要屬性: name、group、jobClass、jobDataMap
System.out.println("名稱:" + jobDetail.getKey().getName());
System.out.println("組的名稱:" + jobDetail.getKey().getGroup()); //如果沒有指定組名:DEFAULT
System.out.println("任務類:" + jobDetail.getJobClass().getName());
JobExecutionContext介紹
- 當Scheduler呼叫一個job,就會將JobExecutionContext傳遞給Job的execute()方法
- Job能通過JobExecutionContext物件訪問到Quartz執行時候的環境以及job本身的明細資料
JobDataMap介紹
- (1)使用Map獲取
- 在進行任務排程時,JobDataMap儲存在JobExecutionContext中,非常方便獲取
- JobDataMap可以用來裝載任何可序列化的資料物件,當job例項物件被執行時這些引數物件會傳遞給它
- JobDataMap實現了JDK的Map介面,並且新增了非常方便的方法用來存取基本資料型別。
比如:在JobDetail和Trigger中都傳遞引數,然後再job中獲取對應的引數
HelloScheduler.java中傳遞引數
//2: 任務例項(JobDetail)
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//載入任務類,與HelloJob(實現Job介面)完成繫結
.withIdentity("job1","group1")//引數1: 任務的名稱(唯一例項); 引數2:任務組的名稱
.usingJobData("message", "列印日誌")
.build();
//3: 觸發器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") //引數1: 觸發器的名稱(唯一例項); 引數2: 觸發器組的名稱
.startNow()//馬上啟動這個觸發器
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).withRepeatCount(5))
.usingJobData("message", "simple觸發器")
.build();
job中獲取傳遞過來的引數值
public class HelloJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//輸出當前時間
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
System.out.println("正在進行資料庫的備份工作,備份資料庫的時間是:" + dateString);
//從JobDetail物件中獲取jobDataMap的資料
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
String jobDataMessage = jobDataMap.getString("message");
System.out.println("任務資料的引數值" + jobDataMessage);
//從Trigger物件中獲取jobDataMap的資料
JobDataMap triggerDataMap = jobExecutionContext.getTrigger().getJobDataMap();
String triggerDataMessage = triggerDataMap.getString("message");
System.out.println("觸發器資料的引數值" + triggerDataMessage);
}
}
在任務執行過程中獲取其他比較重要的值
//獲取其他任務
System.out.println("當前任務的執行時間:" + jobExecutionContext.getFireTime());
System.out.println("下一次任務的執行時間:" + jobExecutionContext.getNextFireTime());
(2) Job實現類中新增setter方法對應JobDataMap的鍵值,Quartz框架預設的JobFactory實現類在初始化job例項物件時會自動地呼叫這些setter方法。
private String message;
public void setMessage(String message){
this.message = message;
}
這裡注意:如果遇到同名的key,Trigger中的.usingJobData("message","simple觸發器")會覆蓋jobDetail中的usingJobData("message", "列印日誌");
有狀態的Job和無狀態的Job
@PersistDataAfterExecution註解的使用
有狀態的job可以理解為多次job呼叫期間可以持有一些狀態資訊,這些狀態資訊儲存在jobDataMap中,而預設的無狀態job每次呼叫時都會建立一個新的JobDataMap
(1)修改HelloScheduler.新增.usingJobData("count", 0), 表示計數器
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//載入任務類,與HelloJob(實現Job介面)完成繫結
.withIdentity("job1","group1")//引數1: 任務的名稱(唯一例項); 引數2:任務組的名稱
.usingJobData("message", "列印日誌")
.usingJobData("count", 0)
.build();
(2)修改Hello.java-新增count的setting和getting方法
private String message;
private Integer count;
public void setCount(Integer count) {
this.count = count;
}
public Integer getCount() {
return count;
}
/*省略一塊邏輯*/
//在execute()方法中
++count;
jobExecutionContext.getJobDetail().getJobDataMap().put("count", count);
結果顯示每次輸出的值都為0
在HelloJob上新增@PersistDataAfterExecution,多次呼叫,會對Job進行持久化,儲存一些資料的資訊
import java.util.Date;
@PersistJobDataAfterExecution
public class HelloJob implements Job {
private String message;
private Integer count;
public void setCount(Integer count) {
this.count = count;
}
執行結果為:count的值變成有狀態的了,被不斷地進行累加
相關文章
- Quartz - Spring和Quartz的整合quartzSpring
- Quartz - Quartz簡單入門quartz
- Quartz定時任務框架(二) Quartz詳解quartz框架
- Quartz 學習quartz
- Quartz 使用教程quartz
- Quartz原理解密quartz解密
- 【Springboot】快速整合QuartzSpring Bootquartz
- SpringBoot 整合 Quartz + MySQLSpring BootquartzMySql
- Quartz 簡單使用quartz
- spring-quartz整合Springquartz
- Quartz.NET 2.x 文件翻譯 - Lesson 1:使用Quartzquartz
- Quartz - Spring整合Quartz實現叢集的定時任務quartzSpring
- Quartz.NET 使用入門整理二(搭建quartz.net專案)quartz
- ApiBoot - ApiBoot Quartz 使用文件APIbootquartz
- Quartz job scheduler 學習quartz
- Quartz (2) - 動態操作quartz
- Quartz框架中的Schedulerquartz框架
- Quartz:基本用法總結quartz
- Quartz.Net系列(六):Quartz五大構件Trigger之TriggerBuilder解析quartzUI
- quartz學習-quartz編碼方式實現定時任務簡例quartz
- 架構 規則引擎 quartz架構quartz
- Quartz在Spring中叢集quartzSpring
- 深入解讀Quartz的原理quartz
- Quartz.NET整合UI版quartzUI
- 石英定時任務-quartzquartz
- springmvc+quartz叢集+sqlserverSpringMVCquartzSQLServer
- Quartz.NET 2.x 文件翻譯 - Lesson 12:Quartz的其他各種特性quartz
- Puppeteer 初探
- gRPC 初探RPC
- ## RATreeView 初探View
- 初探Firewalld
- Serverless初探Server
- Mobx 初探
- 初探PWA
- 初探TCPTCP
- 初探 BaconJSJS
- 初探 TypeScriptTypeScript
- ECharts 初探Echarts