SpringBoot整合Quartz(一)-簡單介紹Demo

SpringBoot整合Quartz(一)-簡單介紹Demo

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

Quartz

引入依賴

因?yàn)槲覀兪褂玫氖?SpringBootQuartz 整合。

如果沒有使用 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);

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容