SpringBoot系列:Spring Boot集成定時(shí)任務(wù)Quartz

一、關(guān)于Quartz

Quartz是OpenSymphony開源組織在Job scheduling領(lǐng)域又一個(gè)開源項(xiàng)目,它可以與J2EE與J2SE應(yīng)用程序相結(jié)合也可以單獨(dú)使用。在java企業(yè)級(jí)應(yīng)用中,Quartz是使用最廣泛的定時(shí)調(diào)度框架。

在Quartz中的主要概念:

  • Scheduler:調(diào)度任務(wù)的主要API
  • ScheduleBuilder:用于構(gòu)建Scheduler,例如其簡(jiǎn)單實(shí)現(xiàn)類SimpleScheduleBuilder
  • Job:調(diào)度任務(wù)執(zhí)行的接口,也即定時(shí)任務(wù)執(zhí)行的方法
  • JobDetail:定時(shí)任務(wù)作業(yè)的實(shí)例
  • JobBuilder:關(guān)聯(lián)具體的Job,用于構(gòu)建JobDetail
  • Trigger:定義調(diào)度執(zhí)行計(jì)劃的組件,即定時(shí)執(zhí)行
  • TriggerBuilder:構(gòu)建Trigger

一、Quartz演示示例

在SpringBoot中,我們需要引入quartz的依賴。

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--quartz定時(shí)調(diào)度依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

首先定義定時(shí)具體執(zhí)行邏輯Job,創(chuàng)建類QuartzJob1,這里集繼承QuartzJobBean實(shí)現(xiàn)executeInternal即可,該方法即定時(shí)執(zhí)行任務(wù)邏輯,這里簡(jiǎn)單打印了下當(dāng)前時(shí)間。

public class QuartzJob1 extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("QuartzJob1----" + sdf.format(new Date()));
    }

}

然后創(chuàng)建QuartzConfig,接著定義JobDetail,JobDetail由JobBuilder構(gòu)建,同時(shí)關(guān)聯(lián)了任務(wù)QuartzJob1。

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail jobDetail1(){
        return JobBuilder.newJob(QuartzJob1.class).storeDurably().build();
    }
    
}

最后我們需要定義定時(shí)調(diào)度Trigger,簡(jiǎn)單實(shí)現(xiàn)類SimpleScheduleBuilder用于構(gòu)建Scheduler,TriggerBuilder則用于構(gòu)建Trigger,

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail jobDetail1(){
        return JobBuilder.newJob(QuartzJob1.class).storeDurably().build();
    }

    @Bean
    public Trigger trigger1(){
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(1) //每一秒執(zhí)行一次
                .repeatForever(); //永久重復(fù),一直執(zhí)行下去
        return TriggerBuilder.newTrigger()
                .forJob(jobDetail1())
                .withSchedule(scheduleBuilder)
                .build();
    }
    
}

這樣一個(gè)Quartz定時(shí)任務(wù)就配置完成了。

其實(shí)Job的定義也可以使用內(nèi)部類,這樣可以省去Job類的創(chuàng)建,例如下面定時(shí)任務(wù)2 jobDetail2和trigger2。

@Bean
public JobDetail jobDetail2(){
    QuartzJobBean quartzJob2 = new QuartzJobBean() {
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("內(nèi)部類quartzJob2----" + sdf.format(new Date()));
        }
    };
    return JobBuilder.newJob(quartzJob2.getClass()).storeDurably().build();
}

@Bean
public Trigger trigger2(){
    //JobDetail的bean注入不能省略
    //JobDetail jobDetail3 = JobBuilder.newJob(QuartzJob2.class).storeDurably().build();
    SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInSeconds(2) //每2秒執(zhí)行一次
            .repeatForever(); //永久重復(fù),一直執(zhí)行下去
    return TriggerBuilder.newTrigger()
            .forJob(jobDetail2())
            .withSchedule(scheduleBuilder).build();
}

啟動(dòng)程序,我們就可以看到控制臺(tái)的時(shí)間輸出了。

同時(shí)Quartz是支持?jǐn)?shù)據(jù)持久化的,可以將定時(shí)調(diào)度信息持久化到數(shù)據(jù)庫。

選擇持久化到數(shù)據(jù)庫,我們需要?jiǎng)?chuàng)建對(duì)應(yīng)的表,建表語句可以在Quartz官網(wǎng)進(jìn)行下載,解壓后在docs\dbTables目錄下尋找對(duì)應(yīng)數(shù)據(jù)庫的SQL腳本。

為了方便,我也將該文件放在了項(xiàng)目源碼resources里。

操作數(shù)據(jù)庫,我們引入相關(guān)的依賴。若有ORM框架,例如mybatis,hibernate或者jpa,則無需再引入jdbc依賴。

<!--mysql連接-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<!--druid連接池-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>

<!--jdbc依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

在application.yml配置文件中,我們對(duì)quartz持久化方式進(jìn)行聲明。

server:
  port: 10900

spring:
  profiles:
    active: dev
  quartz:
    job-store-type: jdbc #持久化到數(shù)據(jù)庫
    properties:
      org:
        quartz:
          datasource:
            # 新版驅(qū)動(dòng)從com.mysql.jdbc.Driver變更為com.mysql.cj.jdbc.Driver
            driver-class-name: com.mysql.cj.jdbc.Driver
            # 數(shù)據(jù)源需要添加時(shí)間標(biāo)準(zhǔn)和指定編碼格式解決亂碼 You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
            url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
            username: root
            password: 1234
          scheduler:
            instancName: clusteredScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate說明支持集群
            tablePrefix: QRTZ_
            isClustered: true
            clusterCheckinInterval: 1000
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 20
            threadPriority: 5

這里主要就是job-store-type: jdbc,表示持久化到數(shù)據(jù)庫,然后就是數(shù)據(jù)源,由于該演示項(xiàng)目沒有其他ORM的數(shù)據(jù)源,所以這里將數(shù)據(jù)源信息定義在了quartz節(jié)點(diǎn)下的datasource節(jié)點(diǎn),如果已經(jīng)存在,可使用同一個(gè)屬性配置,當(dāng)然最關(guān)鍵的是QuartzDataSource聲明。

這里關(guān)鍵的是@QuartzDataSource,這個(gè)要和項(xiàng)目中已經(jīng)存在的數(shù)據(jù)源區(qū)分開。

//Error:EmbeddedDatabaseType class not found,Druid數(shù)據(jù)源初始化需要引入spring-jdbc依賴,JPA或mybatis依賴已經(jīng)包含該依賴
@Bean
@QuartzDataSource
@ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
DataSource quartzDataSource(){
    return DruidDataSourceBuilder.create().build();
}

這樣持久化就已經(jīng)配置好了,我們執(zhí)行sql,再啟動(dòng)項(xiàng)目,啟動(dòng)完成后,我們可以看到數(shù)據(jù)庫中已經(jīng)有我們的定時(shí)調(diào)度數(shù)據(jù)了。

源碼地址:https://github.com/imyanger/springboot-project/tree/master/p25-springboot-quartz

?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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