SpringBoot系列:Spring Boot集成定時任務Quartz

1、關於Quartz

Quartz是OpenSymphony開源組織在Job scheduling領域又一個開源項目,它能夠與J2EE與J2SE應用程序相結合也能夠單獨使用。在java企業級應用中,Quartz是使用最普遍的定時調度框架。java

在Quartz中的主要概念:mysql

  • Scheduler:調度任務的主要API
  • ScheduleBuilder:用於構建Scheduler,例如其簡單實現類SimpleScheduleBuilder
  • Job:調度任務執行的接口,也即定時任務執行的方法
  • JobDetail:定時任務做業的實例
  • JobBuilder:關聯具體的Job,用於構建JobDetail
  • Trigger:定義調度執行計劃的組件,即定時執行
  • TriggerBuilder:構建Trigger

1、Quartz演示示例

在SpringBoot中,咱們須要引入quartz的依賴。git

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

<!--quartz定時調度依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

首先定義定時具體執行邏輯Job,建立類QuartzJob1,這裏集繼承QuartzJobBean實現executeInternal便可,該方法即定時執行任務邏輯,這裏簡單打印了下當前時間。github

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()));
    }

}

而後建立QuartzConfig,接着定義JobDetail,JobDetail由JobBuilder構建,同時關聯了任務QuartzJob1。web

@Configuration
public class QuartzConfig {

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

最後咱們須要定義定時調度Trigger,簡單實現類SimpleScheduleBuilder用於構建Scheduler,TriggerBuilder則用於構建Trigger,spring

@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) //每一秒執行一次
                .repeatForever(); //永久重複,一直執行下去
        return TriggerBuilder.newTrigger()
                .forJob(jobDetail1())
                .withSchedule(scheduleBuilder)
                .build();
    }
    
}

這樣一個Quartz定時任務就配置完成了。sql

其實Job的定義也可使用內部類,這樣能夠省去Job類的建立,例以下面定時任務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("內部類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秒執行一次
            .repeatForever(); //永久重複,一直執行下去
    return TriggerBuilder.newTrigger()
            .forJob(jobDetail2())
            .withSchedule(scheduleBuilder).build();
}

啓動程序,咱們就能夠看到控制檯的時間輸出了。springboot

同時Quartz是支持數據持久化的,能夠將定時調度信息持久化到數據庫。mybatis

選擇持久化到數據庫,咱們須要建立對應的表,建表語句能夠在Quartz官網進行下載,解壓後在docs\dbTables目錄下尋找對應數據庫的SQL腳本。

爲了方便,我也將該文件放在了項目源碼resources裏。

操做數據庫,咱們引入相關的依賴。如有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配置文件中,咱們對quartz持久化方式進行聲明。

server:
  port: 10900

spring:
  profiles:
    active: dev
  quartz:
    job-store-type: jdbc #持久化到數據庫
    properties:
      org:
        quartz:
          datasource:
            # 新版驅動從com.mysql.jdbc.Driver變動爲com.mysql.cj.jdbc.Driver
            driver-class-name: com.mysql.cj.jdbc.Driver
            # 數據源須要添加時間標準和指定編碼格式解決亂碼 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,表示持久化到數據庫,而後就是數據源,因爲該演示項目沒有其餘ORM的數據源,因此這裏將數據源信息定義在了quartz節點下的datasource節點,若是已經存在,可以使用同一個屬性配置,固然最關鍵的是QuartzDataSource聲明。

這裏關鍵的是@QuartzDataSource,這個要和項目中已經存在的數據源區分開。

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

這樣持久化就已經配置好了,咱們執行sql,再啓動項目,啓動完成後,咱們能夠看到數據庫中已經有咱們的定時調度數據了。

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

相關文章
相關標籤/搜索