慕課網_《Java定時任務調度工具詳解之Quartz篇》學習總結

時間:2017年06月26日星期一
說明:本文部份內容均來自慕課網。@慕課網:http://www.imooc.com
教學示例源碼:https://github.com/zccodere/s...
我的學習源碼:https://github.com/zccodere/s...java

第一章:課程介紹

1-1 初識Quartz

Quartz概要git

OpenSymphony提供的強大的開源任務調度框架
官網:http://www.quartz-scheduler.org
純Java實現,精細控制排程

Quartz特色github

強大的調度功能
靈活的應用方式
分佈式和集羣能力

Quartz的設計模式web

Builder模式
Factory模式
組件模式
鏈式寫法

Quartz三個核心概念spring

調度器
任務
觸發器

Quartz體系結構apache

JobDetail
trigger
    SimpleTrigger
    CronTrigger
scheduler
    start
    stop
    pause
    resume

示意圖設計模式

clipboard.png

Quartz重要組成springboot

Job
JobDetail
JobBuilder
JobStore
Trigger
TriggerBuilder
ThreadPool
Scheduler
Calendar:一個Trigger能夠和多個Calendar關聯,以排除或包含某些時間點
監聽器
    JobListener
    TriggerListener
    SchedulerListener

第二章:Quartz詳解

2-1 第一個Quartz程序

準備工做框架

創建Maven項目工程
引入Quartz包

編寫第一個Quartz任務maven

讓任務每隔兩秒打印一次hellworld

代碼演示

1.編寫任務類

package com.myimooc.helloquartz.one;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * 編寫 自定義任務
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloJob implements Job{
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        
        // 編寫具體的業務邏輯
        System.out.println("Hello World!");
    }
    
}

2.編寫任務調度類

package com.myimooc.helloquartz.one;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

/**
 * 編寫 任務調度類
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloScheduler {
    
    public static void main(String[] args) throws SchedulerException {
        
        // 建立一個 JobDetail 實例,將該實例與 HelloJob 實例綁定
        JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myjob", "jobgroup1")// 定義標識符
                .build();
        
        System.out.println("jobDetail's name : " + jobDeatil.getKey().getName());
        System.out.println("jobDetail's group : " + jobDeatil.getKey().getGroup());
        System.out.println("jobDetail's jobClass : " + jobDeatil.getJobClass().getName());
        
        // 建立一個 Trigger 實例,定義該 job 當即執行,而且每隔兩秒重複執行一次,直到永遠
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("myTrigger","trigroup1")// 定義標識符
                .startNow()// 定義當即執行
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(2)
                        .repeatForever())// 定義執行頻度
                .build();
        
        // 建立 Scheduler 實例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        
        // 綁定 JobDetail 和 trigger
        scheduler.scheduleJob(jobDeatil, trigger);
        
        // 執行任務
        scheduler.start();
        
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
    }
    
}

2-2 淺談Job&JobDetail

Job定義

實現業務邏輯的任務接口

淺談Job

Job接口很是容易實現,只有一個execute方法,相似TimerTask的run方法,在裏面編寫業務邏輯
Job接口源碼
public interface Job {
    void execute(JobExecutionContext context) throws JobExecutionException;
}

Job實例在Quartz中的生命週期

每次調度器執行job時,它在調用execute方法前會建立一個新的job實例
當調用完成後,關聯的job對象實例會被釋放,釋放的實例會被垃圾回收機制回收

淺談JobDetail

JobDetail爲Job實例提供了許多設置屬性,以及JobDetailMap成員變量屬性,它用來存儲特定Job實例的狀態信息,調度器須要藉助JobDetail對象來添加Job實例。

JobDetail屬性

name:任務名稱
group:任務所屬組
jobClass:任務實現類
jobDataMap:傳參的做用

2-3 淺談JobExecutionContext&JobDataMap(上)

JobExecutionContext是什麼

當Scheduler調用一個Job,就會將JobExecutionContext傳遞給Job的execute()方法;
Job能經過JobExecutionContext對象訪問到Quartz運行時候的環境以及Job自己的明細數據。

JobDataMap是什麼

在進行任務調度時JobDataMap存儲在JobExecutionContext中,很是方便獲取
JobDataMap能夠用來裝載任務可序列化的數據對象,當job實例對象被執行時這些參數對象會傳遞給它
JobDataMap實現了JDK的Map接口,而且添加了一些很是方便的方法用來存取基本數據類型

2-4 淺談JobExecutionContext&JobDataMap(下)

獲取JobDataMap的兩種方式

從Map中直接獲取
Job實現類中添加setter方法對應JobDataMap的鍵值
(Quartz框架默認的JobFactory實現類在初始化job實例對象時會自動地調用這些setter方式)

代碼演示

1.HelloScheduler類改造

package com.myimooc.helloquartz.two;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

/**
 * 編寫 任務調度類
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloScheduler {
    
    public static void main(String[] args) throws SchedulerException {
        
        // 建立一個 JobDetail 實例,將該實例與 HelloJob 實例綁定
        JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myjob", "jobgroup1")// 定義標識符
                .usingJobData("message", "hello myjob1")// 傳入自定義參數
                .usingJobData("floatJobValue", 3.14F)// 傳入自定義參數
                .build();
        
        System.out.println("jobDetail's name : " + jobDeatil.getKey().getName());
        System.out.println("jobDetail's group : " + jobDeatil.getKey().getGroup());
        System.out.println("jobDetail's jobClass : " + jobDeatil.getJobClass().getName());
        
        // 建立一個 Trigger 實例,定義該 job 當即執行,而且每隔兩秒重複執行一次,直到永遠
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("myTrigger","trigroup1")// 定義標識符
                .usingJobData("message", "hello mytrigger1")// 傳入自定義參數
                .usingJobData("doubleTriggerValue", 2.0D)// 傳入自定義參數
                .startNow()// 定義當即執行
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(2)
                        .repeatForever())// 定義執行頻度
                .build();
        
        // 建立 Scheduler 實例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        
        // 綁定 JobDetail 和 trigger
        scheduler.scheduleJob(jobDeatil, trigger);
        
        // 執行任務
        scheduler.start();
        
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
    }
    
}

2.HelloJob類改造

package com.myimooc.helloquartz.two;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.TriggerKey;

/**
 * 編寫 自定義任務
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloJob implements Job{
    
    // 方式二:getter和setter獲取
    // 成員變量 與 傳入參數的key一致
    private String message;
    private Float floatJobValue;
    private Double doubleTriggerValue;
    
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Float getFloatJobValue() {
        return floatJobValue;
    }
    public void setFloatJobValue(Float floatJobValue) {
        this.floatJobValue = floatJobValue;
    }
    public Double getDoubleTriggerValue() {
        return doubleTriggerValue;
    }
    public void setDoubleTriggerValue(Double doubleTriggerValue) {
        this.doubleTriggerValue = doubleTriggerValue;
    }
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        
        // 編寫具體的業務邏輯
        //System.out.println("Hello World!");
        
        JobKey key = context.getJobDetail().getKey();
        System.out.println("My name and group are : " + key.getName() + " : " + key.getGroup());
        
        TriggerKey trkey = context.getTrigger().getKey();
        System.out.println("My Trigger name and group are : " + trkey.getName() + " : " + trkey.getGroup());
        
        // 方式一:Map中直接  獲取自定義參數
        JobDataMap jdataMap = context.getJobDetail().getJobDataMap();
        JobDataMap tdataMap = context.getTrigger().getJobDataMap();
        String jobMsg = jdataMap.getString("message");
        Float jobFloatValue = jdataMap.getFloat("floatJobValue");
        
        String triMsg = tdataMap.getString("message");
        Double triDoubleValue = tdataMap.getDouble("doubleTriggerValue");
        
        System.out.println("jobMsg is : " + jobMsg);
        System.out.println("jobFloatValue is : " + jobFloatValue);
        System.out.println("triMsg is : " + triMsg);
        System.out.println("triDoubleValue is : " + triDoubleValue);
        
        // 方式一:Map中直接獲取 獲取自定義參數
        JobDataMap jobDataMap = context.getMergedJobDataMap();
        jobMsg = jobDataMap.getString("message");
        jobFloatValue = jobDataMap.getFloat("floatJobValue");
        
        triMsg = jobDataMap.getString("message");
        triDoubleValue = jobDataMap.getDouble("doubleTriggerValue");
        
        System.out.println("jobMsg is : " + jobMsg);
        System.out.println("jobFloatValue is : " + jobFloatValue);
        System.out.println("triMsg is : " + triMsg);
        System.out.println("triDoubleValue is : " + triDoubleValue);
        
        // 方式二:getter和setter獲取
        System.out.println("message is : " + this.message);
        System.out.println("jobFloatValue is : " + this.floatJobValue);
        System.out.println("triDoubleValue is : " + this.doubleTriggerValue);
    }
    
}

2-5 淺談Trigger

Trigger是什麼

Quartz中的觸發器用來告訴調度程序做業何時觸發
即Trigger對象時用來觸發執行Job的

Quartz框架中的Trigger示意圖

clipboard.png

觸發器通用屬性

JobKey:表示job實例的標識,觸發器被觸發時,該指定的job實例會執行
StartTime:表示觸發器的時間表首次被觸發的時間,它的值的類型是Java.util.Date
EndTime:指定觸發器的再也不被觸發的時間,它的值的類型是Java.util.Date

代碼演示

1.HelloJob類改造

package com.myimooc.helloquartz.three;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Trigger;

/**
 * 自定義任務  觸發器通用屬性
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloJob implements Job{
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        
        Trigger currentTrigger = context.getTrigger();
        System.out.println("Start Time Is : " + sf.format(currentTrigger.getStartTime()));
        System.out.println("End Time Is : " + sf.format(currentTrigger.getEndTime()));
        
        JobKey jobKey = currentTrigger.getJobKey();
        System.out.println("JobKey info : " + " jobName : " + jobKey.getName()
                + " jobGroup : " + jobKey.getGroup());
    }
    
}

2.HelloScheduler類改造

package com.myimooc.helloquartz.three;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

/**
 * 任務調度類  觸發器通用屬性
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloScheduler {
    
    public static void main(String[] args) throws SchedulerException {
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
        
        // 建立一個 JobDetail 實例,將該實例與 HelloJob 實例綁定
        JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myjob", "jobgroup1")// 定義標識符
                .build();
        
        // 獲取距離當前時間3秒後的時間
        date.setTime(date.getTime() + 3000);
        // 獲取距離當前時間6秒後的時間
        Date endDate = new Date();
        endDate.setTime(endDate.getTime() + 6000);
        
        // 建立一個 Trigger 實例,定義該 job 當即執行,而且每隔兩秒重複執行一次,直到永遠
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("myTrigger","trigroup1")// 定義標識符
                .startAt(date)// 定義3秒後執行
                .endAt(endDate)// 定義6秒後結束
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(2)
                        .repeatForever())// 定義執行頻度
                .build();
        
        // 建立 Scheduler 實例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        
        // 綁定 JobDetail 和 trigger
        scheduler.scheduleJob(jobDeatil, trigger);
        
        // 執行任務
        scheduler.start();
    }
    
}

2-6 SimpleTrigger

SimpleTrigger的做用

在一個指定時間段內執行一次做業任務
或是在指定的時間間隔內屢次執行做業任務

須要注意的點

重複次數能夠爲0,正整數或是SimpleTrigger.REPEAT_INDEFINITELY常量值
重複執行間隔必須爲0或長整數
一旦被指定了endTime參數,那麼它會覆蓋重複次數參數的效果

代碼演示

1.HelloJob類改造

package com.myimooc.helloquartz.four;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * SimpleTrigger 演示
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloJob implements Job{
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        
        System.out.println("Hello World!");
    }
    
}

2.HelloScheduler類改造

package com.myimooc.helloquartz.four;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

/**
 * SimpleTrigger 演示
 * @author ZhangCheng on 2017-06-26
 *
 */
public class HelloScheduler {
    
    public static void main(String[] args) throws SchedulerException {
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
        
        // 建立一個 JobDetail 實例,將該實例與 HelloJob 實例綁定
        JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myjob", "jobgroup1")// 定義標識符
                .build();
        
        // 獲取距離當前時間4秒鐘以後的具體時間
        date.setTime(date.getTime() + 4000);
        // 獲取距離當前時間6秒鐘以後的具體時間
        Date endDate = new Date();
        endDate.setTime(endDate.getTime() + 6000);
        
        // 距離當前時間4秒鐘後首次執行任務,以後每隔2秒鐘重複執行一次任務
        // 知道距離當前時間6秒鐘以後爲止
        SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger","trigroup1")// 定義標識符
                .startAt(date)
                .endAt(endDate)
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(2)
                        .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY))
                .build();
         
        // 建立 Scheduler 實例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.scheduleJob(jobDeatil, trigger);
        scheduler.start();
    }
    
}

2-7 CronTrigger

CronTrigger的做用

基於日曆的做業調度器,而不是像SimpleTrigger那樣精確指定間隔時間,比SimpleTrigger更經常使用

Cron表達式

用於配置CronTrigger實例
是由7個子表達式組成的字符串,描述了時間表的詳細信息
格式:[秒][分][小時][日][月][周][年]

Cron表達式特殊字符意義對應表

clipboard.png

特殊符號解釋

clipboard.png

Cron表達式舉例

clipboard.png

Cron表達式小提示

L和W能夠一組合使用
周字段英文字母不區分大小寫即MON與mon相同
利用工具,在線生成

2-8 淺談Scheduler

Scheduler工廠模式

全部的Scheduler實例應該由SchedulerFactory來建立

SchedulerFactory類圖

clipboard.png

回顧Quartz三個核心概念

調度器
任務
觸發器

示意圖

clipboard.png

Scheduler的建立方式

clipboard.png

StdSchedulerFactory

使用一組參數(Java.util.Properties)來建立和初始化Quartz調度器
配置參數通常存儲在quartz.properties中
調用getScheduler方法就能建立和初始化調度器對象

Scheduler的主要函數

// 綁定 jobDetail 和 trigger,將它註冊進 Scheduler 當中
Date scheduleJob(JobDetail jobDetail, Trigger trigger)
// 啓動 Scheduler
void start()
// 暫停 Scheduler
void standby()
// 關閉 Scheduler
void shutdown()

2-9 QuartzProperties文件

quartz.properties組成部分

調度器屬性
線程池屬性
做業存儲設置
插件配置

調度器屬性

clipboard.png

線程池屬性

threadCount:工做線程數量
threadPriority:工做線程優先級
org.quartz.threadPool.class:配置線程池實現類

做業存儲設置

描述了在調度器實例的生命週期中,Job和Trigger信息是如何被存儲的

插件配置

知足特定需求用到的Quartz插件的配置

第三章:Spring、Quartz大合體

3-1 搭建工程

基於Maven建立一個簡單的SpringMVC工程,學習時,使用springboot框架。

項目POM文件

<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.myimooc</groupId>
  <artifactId>springquartz</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springquartz</name>
  <url>http://maven.apache.org</url>

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
  
  <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
</project>

項目目錄結構

clipboard.png

3-2 Quartz和Spring大合體

使用Quartz配置做業兩種方式

MethodInvokingJobDetailFactoryBean
JobDetailFactoryBean

方式一:使用MethodInvokingJobDetailFactoryBean

1.調用myBean的printMessage方法

clipboard.png

2.MyBean類

clipboard.png

方式二:使用JobDetailFactoryBean

1.須要給做業傳遞數據,想要更加靈活的話就是用這種方式

clipboard.png

2.FirstScheduleJob類

clipboard.png

3.AnotherBean類

clipboard.png

代碼演示:

演示說明:教學基於xml進行配置,學習時基於javaconfig進行配置。

1.編寫MyBean類

package com.myimooc.springquartz.quartz;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.stereotype.Component;

/**
 * 方式一:使用MethodInvokingJobDetailFactoryBean 演示
 * @author ZhangCheng on 2017-06-28
 *
 */
@Component
public class MyBean {
    
    public void printMessage(){
        
        // 打印當前的執行時間,格式爲2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        System.out.println("MyBean Executes!" + sf.format(date));
    }
    
}

2.編寫AnotherBean類

package com.myimooc.springquartz.quartz;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.stereotype.Component;

/**
 * 方式二:使用JobDetailFactoryBean 演示
 * @author ZhangCheng on 2017-06-28
 *
 */
@Component
public class AnotherBean {
    
    public void printAnotherMessage(){
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        System.out.println("I am AnotherBean." + sf.format(date));
    }
    
}

3.編寫FirstScheduledJob類

package com.myimooc.springquartz.quartz;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * 方式二:使用JobDetailFactoryBean 演示
 * @author ZhangCheng on 2017-06-28
 *
 */
public class FirstScheduledJob extends QuartzJobBean {
    
    private AnotherBean anotherBean;
    
    public void setAnotherBean(AnotherBean anotherBean) {
        this.anotherBean = anotherBean;
    }

    @Override
    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        System.out.println("FirstScheduledJob Excutes!" + sf.format(date));
        this.anotherBean.printAnotherMessage();
    }

}

4.編寫QuartzConfig類

package com.myimooc.springquartz.config;

import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

import com.myimooc.springquartz.quartz.AnotherBean;
import com.myimooc.springquartz.quartz.FirstScheduledJob;
import com.myimooc.springquartz.quartz.MyBean;

/**
 * Quartz 配置類
 * @author ZhangCheng on 2017-06-28
 *
 */
@Configuration
public class QuartzConfig {
    
    @Autowired
    private MyBean myBean;
    
    @Autowired
    private AnotherBean anotherBean;
    
    /**
     * 方式一:使用MethodInvokingJobDetailFactoryBean
     * @return
     */
    @Bean
    public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean(){
        MethodInvokingJobDetailFactoryBean mb = new MethodInvokingJobDetailFactoryBean();
        mb.setTargetObject(myBean);// 指定要運行的類
        mb.setTargetMethod("printMessage");// 指定要容許類中的那個方法
        return mb;
    }
    
    /**
     * 方式二:使用JobDetailFactoryBean
     * @return
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean  jb= new JobDetailFactoryBean();
        jb.setJobClass(FirstScheduledJob.class);// 指定要運行的類
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("anotherBean", anotherBean);
        
        jb.setJobDataMap(jobDataMap);// 設置傳入自定義參數
        jb.setDurability(true);
        return jb;
    }
    
    /**
     * 配置 SimpleTriggerFactoryBean
     * @return
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(){
        SimpleTriggerFactoryBean sb = new SimpleTriggerFactoryBean();
        sb.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());// 設置須要綁定的 jobDetail
        sb.setStartDelay(1000L);// 距離當前時間1秒後執行
        sb.setRepeatInterval(2000L);// 以後每隔2秒執行一次
        return sb;
    }
    
    /**
     * 配置 SimpleTriggerFactoryBean
     * @return
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(){
        CronTriggerFactoryBean cb = new CronTriggerFactoryBean();
        cb.setJobDetail(jobDetailFactoryBean().getObject());// 設置須要綁定的 jobDetail
        cb.setStartDelay(1000L);// 距離當前時間1秒後執行
        cb.setCronExpression("0/5 * * ? * *");// 設置 Cron 表達式,以後每隔5秒執行一次
        return cb;
    }
    
    /**
     * 配置 SchedulerFactoryBean
     * @return
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(){
        SchedulerFactoryBean sb= new SchedulerFactoryBean();
        // 配置 JobDetails
        JobDetail[] jobDetails = new JobDetail[2];
        jobDetails[0] = methodInvokingJobDetailFactoryBean().getObject();
        jobDetails[1] = jobDetailFactoryBean().getObject();
        sb.setJobDetails(jobDetails);
        
        // 配置 Trigger
        Trigger[] triggers = new Trigger[2];
        triggers[0] = simpleTriggerFactoryBean().getObject();
        triggers[1] = cronTriggerFactoryBean().getObject();
        sb.setTriggers(triggers);
        return sb;
        
    }
}

第四章:課程總結

4-1 課程總結

課程回顧

Timer
Quartz
Quartz&Spring融合
相關文章
相關標籤/搜索