Quartz簡介
Quartz是Job Scheduling(任務調度)領域的開源項目,可單獨使用,也可和JavaSE,EE進行組合,是一個任務調度管理系統,可在特定的時間內執行特定的任務,如想在Java中使用Quartz,則只需將Quartz的jar包導入到項目中即可.
Quartz相關介紹
Jobs:任務
是實際想要執行的操作,只需要實現Job接口即可.
package com.dong.controller;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class jobtask implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//所要執行的操作
}
}
JobDetail對象:
public static void main(String[] args) {
JobDetail jobtask = newJob(jobTask.class)
.withIdentity("jobone","jobA")
.build();
}
JobDetail對象,在上面的實例中,引入了JobBuilder類的靜態方法newJob來創建job實例,withIdentity用來表示job的名字和所屬組,build()方法則返回一個JobDetail實例.
JobDetail的源碼解釋爲:
/**
*Conveys the detail properties of a given <code>Job</code> instance. JobDetails are
* to be created/defined with {@link JobBuilder}.
*
* <p>
* Quartz does not store an actual instance of a <code>Job</code> class, but
* instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
* </p>
**/
即Quartz不能存儲Job實例,當Quartz需要Job的信息時,可定義JobDetail來存儲Job屬性,JobDetail通過JobBuilder創建.
public static JobBuilder newJob(Class <? extends Job> jobClass) {
JobBuilder b = new JobBuilder();
b.ofType(jobClass);
return b;
}
Job的調度是通過scheduler實例,scheduler傳入JobDetail對象和Trigger對象,JobDetail對象則在構造的過程中傳入Job對象的class對象,可以看出這裏使用反射的機制進行創建Job對象,當每次調用execute方法,則創建一個Job對象,然後丟棄該對象的引用,因此,Job對象必須有一個空參的構造器,其次,Job對象的屬性值不會保存,如果想在Job對象執行中使用配置和屬性,則可以使用JobDataMap.
public class jobTask implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String name =context.getJobDetail().getJobDataMap().getString("name");
System.out.println("name");
}
public static void main(String[] args) {
JobDetail jobtask = newJob(jobTask.class)
.withIdentity("jobone","jobA")
.usingJobData("name","land")
.build();
}
}
JobDataMap可以包含數據對象,可在Job執行過程中,使用該對象的數據.
Trigger:觸發器
Trigger公共屬性:TriggerKey屬性,表明Trigger身份,jobKey:Trigger被觸發時被執行的Job身份,startTime屬性:設置第一次觸發時間,endTime屬性:觸發失效時間.錯過觸發misfire.
Trigger優先級,默認爲5,可以是任意數值,注意只有同一時刻觸發的trigger之間纔會比較優先級.
calendar:不是Java的日曆對象,這個對象用於從trigger的調度計劃中排除時間段,創建Calendar需要實現Calendar接口,然後實例化改對象,並添加到scheduler對象中.對於一整天的排除,則可以使用HolidayCalendar對象,方法modifiedByCalendar()方法將在任務調度時,排除在該時間段的任務.
public static void main(String[] args) {
HolidayCalendar holidayCalendar = new HolidayCalendar();
holidayCalendar.addExcludedDate("xxx");
Trigger trigger = newTrigger()
.withIdentity("triggerone")
.forJob("job")
.withSchedule(dailyAtHourAndMinute(12,00))
.modifiedByCalendar("holidayCalendar")
.build();
}
Trigger兩個子類有Siimple Trigger,Cron Trigger.
Simple Trigger:在特定的時間點支持,或者在特定的時間點執行,然後以特定的時間間隔執行.
CronTrigger 基於日曆概念,使用CronTrigger需要指定時間表,Cron Expressions是用來定義日曆的表達式,“0 0 12?* WED“ - 這意味着”每個星期三下午12:00“。
創建和Triigger對象相同,可以通過設置觸發器的名字,開始時間,結束時間,執行次數,調度器,指定Job來實現任務的觸發操作.
TriggerListeners和JobListeners:前者用來監聽觸發器,後者用來監聽Job.監聽器只需要實現TriggerListener或JobListeners接口即可,可以擴展JobListenerSupport類或TriggerListenerSupport類, listener與調度程序的ListenerManager一起註冊,並配有描述listener希望接收事件的job/觸發器的Matcher。
SchedulerListener監聽器,包含各種監聽Shceduler的事件,和TriggerListenners與JobListeners類型,需要註冊到調度程序的ListennerManager。以JobListener爲例:
package com.dong.controller;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
public class JobLis implements JobListener {
@Override
public String getName() {
return "jobpre";
}
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
System.out.println("Job Start >...");
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
}
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
System.out.println("Job end >....");
}
}
可通過jobExecutionContext來獲取Job在運行時的一些數據.
Schedule:調度器
可通過StdSchedulerFactory,DirectSchedulerFactory來實現,也可通過schedulerFactory獲取.
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
Scheduler scheduler = schedulerFactory.getScheduler();
Quartz在使用前,需要進行實例化,可以使用SchedulerFactory進行實例化,以工廠模式生成一個實例對象,scheduler實例化後,可啓動,暫停,停止.除非scheduler啓動,纔可以進行相應的任務執行操作.
完整的任務調度案例:使用Maven方式創建工程
1.創建工程,pom.xml導入依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dong.quartz</groupId>
<artifactId>quartz_helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加Scheduled座標 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Sprng tx 座標 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>
2.創建Job類
package com.dong.controller;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
@Component
public class JobIns implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("執行 Ququ ...." );
}
}
3.創建JobListeners
package com.dong.controller;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
public class JobLis implements JobListener {
@Override
public String getName() {
return "jobpre";
}
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
System.out.println("Job Start >...");
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
}
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
System.out.println("Job end >....");
}
}
4.創建Trigger Listenner
package com.dong.controller;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;
public class TriggerLis implements TriggerListener {
@Override
public String getName() {
return "triggerpre";
}
@Override
public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
}
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
return false;
}
@Override
public void triggerMisfired(Trigger trigger) {
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
System.out.println("trigger complete > .....");
}
}
5.創建配合類,Simplejob,Trigger,Scheduler
package com.dong.config;
import com.dong.controller.JobLis;
import com.dong.controller.TriggerLis;
import com.dong.controller.JobIns;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
@Configuration
public class QuartzConfig {
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(JobIns.class);
return jobDetailFactory;
}
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactory){
SimpleTriggerFactoryBean simpleTriggerFactory = new SimpleTriggerFactoryBean();
simpleTriggerFactory.setJobDetail(jobDetailFactory.getObject());
simpleTriggerFactory.setRepeatInterval(2000);
simpleTriggerFactory.setRepeatCount(20);
return simpleTriggerFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactory){
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setTriggers(simpleTriggerFactory.getObject());
schedulerFactory.setGlobalJobListeners(new JobLis());
schedulerFactory.setGlobalTriggerListeners(new TriggerLis());
return schedulerFactory;
}
}
6.創建啓動類
package com.dong.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@SpringBootApplication
@EnableScheduling
@ComponentScan("com.dong.*")
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class,args);
}
}
7.運行結果爲:
Job Start >...
執行 Ququ ....
Job end >....
trigger complete > .....
Job Start >...
執行 Ququ ....
Job end >....
trigger complete > .....
如有異議,敬請指出,與君共勉.