SpringBoot整合Quartz(一)-簡單介紹Demo
Quartz 作為一款由 Java 編寫的開源作業(yè)調(diào)度框架,官網(wǎng)傳送門。與我而言,作用是定時(shí)執(zhí)行某一個(gè)任務(wù)。

引入依賴
因?yàn)槲覀兪褂玫氖?SpringBoot 和 Quartz 整合。
如果沒有使用 spring-boot-gradle-plugin 指定SpringBoot的版本,則需要在下面的依賴匯中加入版本號(hào)。
// Gradle 方式
compile('org.springframework.boot:spring-boot-starter-quartz')
// Maven 方式
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
配置文件-Quartz.properties
通過配置文件 quartz.properties,初始化 Quartz 的一些配置.
// ThreadPool 實(shí)現(xiàn)的類名
org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
// 線程數(shù)量
org.quartz.threadPool.threadCount : 10
// 線程優(yōu)先級(jí)
// threadPriority 屬性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值為常量 java.lang.Thread.MIN_PRIORITY,為1
org.quartz.threadPool.threadPriority : 5
// 自創(chuàng)建父線程
//org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
配置Config
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.io.IOException;
import java.util.Properties;
/**
* @description:
* @date: 2018-11-05 17:27
*/
@Configuration
@EnableScheduling
public class SchedulerConfig {
@Bean(name = "SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//在quartz.properties中的屬性被讀取并注入后再初始化對(duì)象
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/**
* quartz初始化監(jiān)聽器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/**
* 通過SchedulerFactoryBean獲取Scheduler的實(shí)例
*/
@Bean(name = "Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
}
常用屬性與方法
1.Job類
繼承 Job 類,表明子類是一個(gè)任務(wù)(Job 的子類必須存在一個(gè)無參構(gòu)造。)。實(shí)現(xiàn) execute(JobExecutionContext context) 方法,來定義任務(wù)的執(zhí)行內(nèi)容。
/**
* 例子:定義一個(gè)執(zhí)行輸出語句的任務(wù)
* @date: 2018-11-05 17:31
*/
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello執(zhí)行:" + LocalDateTime.now());
}
}
2.JobDetails接口
Job 在執(zhí)行時(shí),通過 JobDetails 反射出具體的執(zhí)行對(duì)象。包含了 Job 在執(zhí)行時(shí)的具體屬性。
JobDetailImpl 實(shí)現(xiàn) JobDetails,定義所有的屬性,包括以下幾個(gè):
| 屬性名 | 說明 |
|---|---|
| name | Job任務(wù)的名稱 |
| group | 組。注意:同組中只能存在一個(gè) JobClass 在執(zhí)行。 |
| description | 描述。 |
| jobClass | 具體的 Job。必須是 Job 的實(shí)現(xiàn)類。 |
| jobDataMap | 自定義的屬性??蓪⑷蝿?wù)的 key-value 存入 map 中,實(shí)現(xiàn) Job 屬性的擴(kuò)展。 |
| durability | 是否持久化(默認(rèn)false)。非持久化的 Job,會(huì)在 Trigger 執(zhí)行完畢后,自動(dòng)刪除。 |
| shouldRecover | 是否可恢復(fù)(默認(rèn)false)。當(dāng)設(shè)置為“是”,執(zhí)行 Scheduler 發(fā)生崩潰等異常情況時(shí),Job 會(huì)在 Scheduler 重啟時(shí),重新執(zhí)行。 |
| key | 鍵,標(biāo)識(shí) |
/**
* 通過 JobBuilder 獲得一個(gè) JobDetails 對(duì)象
*/
public JobDetail getJobDetail(String jobClassName, String jobGroupName){
return JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName, jobGroupName).build();
}
/**
* 通過class 實(shí)例對(duì)象
*/
private static BaseJob getClass(String classname) throws Exception {
Class<?> class1 = Class.forName(classname);
return (BaseJob) class1.newInstance();
}
3.Trigger
觸發(fā)器類,包含著 Job 的觸發(fā)執(zhí)行時(shí)間規(guī)則。
| 子類 | 說明 |
|---|---|
| SimpleTrigger | 當(dāng)僅需要觸發(fā)一次,或者以固定時(shí)間間隔周期執(zhí)行時(shí),最合適 |
| CronTrigger | 通過 cron表達(dá)式 定義時(shí)間規(guī)則的調(diào)度方案 |
/**
* 創(chuàng)建一個(gè) Trigger 觸發(fā)器
*/
public Trigger getTrigger(String jobClassName, String jobGroupName, String cronExpression){
//表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
.withSchedule(scheduleBuilder).build();
return trigger;
}
4.JobStore
存儲(chǔ)Job和運(yùn)行期間的狀態(tài)。
默認(rèn)使用的是 RAMJobStore ,使用內(nèi)存來配置、構(gòu)造和運(yùn)行,但是當(dāng)程序停止或者重啟后,任務(wù)就會(huì)丟失。
后面我們會(huì)通過修改 JobStore 來使,Job和Trigger持久化到數(shù)據(jù)庫中。也會(huì)更利于我們使用集群
5.Scheduler
調(diào)度器,是 Quartz 調(diào)用執(zhí)行 Job,以及設(shè)置 trigger 的主要接口。
| 常用方法 | 說明 |
|---|---|
| start() | 開啟調(diào)度線程,也就是啟動(dòng)Scheduler。 |
| shutdown() | 關(guān)閉。 |
| setJobFactory(JobFactory factory) | 指定生成 Job 的JobFactory。 |
| scheduleJob(JobDetail jobDetail, Trigger trigger) | 接收一個(gè)Job,按照指定的 trigger執(zhí)行。 |
| deleteJob(JobKey jobKey) | 刪除 Job。 |
| pauseJob(JobKey jobKey) | 暫停 Job。 |
| pauseTrigger(TriggerKey triggerKey) | 暫停 Trigger。 |
| resumeJob(JobKey jobKey) | 重啟。 |
| rescheduleJob(TriggerKey triggerKey, Trigger newTrigger) | 修改。 |
測(cè)試
@Test
public void quartzTest() throws SchedulerException{
// 1. 創(chuàng)建工廠類 SchedulerFactory
SchedulerFactory factory = new StdSchedulerFactory();
// 2. 通過 getScheduler() 方法獲得 Scheduler 實(shí)例
Scheduler scheduler = factory.getScheduler();
// 3. 使用上文定義的 HelloJob
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
//job 的name和group
.withIdentity("jobName", "jobGroup")
.build();
//3秒后啟動(dòng)任務(wù)
Date statTime = new Date(System.currentTimeMillis() + 3000);
// 4. 啟動(dòng) Scheduler
scheduler.start();
// 5. 創(chuàng)建Trigger
//使用SimpleScheduleBuilder或者CronScheduleBuilder
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("jobTriggerName", "jobTriggerGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //兩秒執(zhí)行一次
.build();
// 6. 注冊(cè)任務(wù)和定時(shí)器
scheduler.scheduleJob(jobDetail, trigger);
}