SpringBoot整合Quartz調(diào)度框架實(shí)現(xiàn)任務(wù)調(diào)度(附學(xué)習(xí)源碼)
來(lái)源:gyoomi.blog.csdn.net/article/details/83382000
一、引言
定時(shí)任務(wù)調(diào)度是Java開(kāi)發(fā)中不可或缺的重要部分,但是Java自帶的Time等任務(wù)調(diào)度類在實(shí)際項(xiàng)目中不好用。所以Quartz和Spring Task就成了我們項(xiàng)目開(kāi)發(fā)技術(shù)選型最多的,在這里我們著重探討一下Quartz在Spring Boot 2.X版本中的使用。
二、Quartz
1. 介紹
Quartz是OpenSymphony開(kāi)源組織在Job scheduling領(lǐng)域的開(kāi)源項(xiàng)目,它可以與J2EE與J2SE應(yīng)用程序相結(jié)合也可以單獨(dú)使用。Quartz可以用來(lái)創(chuàng)建簡(jiǎn)單或?yàn)檫\(yùn)行十個(gè),百個(gè),甚至是好幾萬(wàn)個(gè)Jobs這樣復(fù)雜的日程序表。Jobs可以做成標(biāo)準(zhǔn)的Java組件或 EJBs。
Quartz是一個(gè)任務(wù)日程管理系統(tǒng),一個(gè)在預(yù)先確定(被納入日程)的時(shí)間到達(dá)時(shí),負(fù)責(zé)執(zhí)行(或者通知)其他軟件組件的系統(tǒng)。
Quartz用一個(gè)小Java庫(kù)發(fā)布文件(.jar文件),這個(gè)庫(kù)文件包含了所有Quartz核心功能。這些功能的主要接口(API)是Scheduler接口。它提供了簡(jiǎn)單的操作,例如:將任務(wù)納入日程或者從日程中取消,開(kāi)始/停止/暫停日程進(jìn)度。
2.安裝配置
官方網(wǎng)站:
http://quartz-scheduler.org/
3.設(shè)計(jì)架構(gòu)
介紹
Scheduler – 核心調(diào)度器 Job – 任務(wù) JobDetail – 任務(wù)描述 Trigger – 觸發(fā)器
圖示

多個(gè)定時(shí)的圖示如下:

對(duì)比下配置xml中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!--
Spring整合Quartz進(jìn)行配置遵循下面的步驟:
1:定義工作任務(wù)的Job
2:定義觸發(fā)器Trigger,并將觸發(fā)器與工作任務(wù)綁定
3:定義調(diào)度器,并將Trigger注冊(cè)到Scheduler
-->
<!-- 1:定義任務(wù)的bean ,這里使用JobDetailFactoryBean,也可以使用MethodInvokingJobDetailFactoryBean ,配置類似-->
<bean name="hwJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!-- 指定job的名稱 -->
<property name="name" value="hw_job"/>
<!-- 指定job的分組 -->
<property name="group" value="hw_group"/>
<!-- 指定具體的job類 -->
<property name="jobClass" value="com.dufy.spring.quartz.chapter01.job.HelloWorldJob"/>
<!-- 必須設(shè)置為true,如果為false,當(dāng)沒(méi)有活動(dòng)的觸發(fā)器與之關(guān)聯(lián)時(shí)會(huì)在調(diào)度器中會(huì)刪除該任務(wù) -->
<property name="durability" value="true"/>
<!-- 指定spring容器的key,如果不設(shè)定在job中的jobmap中是獲取不到spring容器的 -->
<property name="applicationContextJobDataKey" value="applicationContext"/>
</bean>
<!-- 2.1:定義觸發(fā)器的bean,定義一個(gè)Simple的Trigger,一個(gè)觸發(fā)器只能和一個(gè)任務(wù)進(jìn)行綁定 -->
<!-- <bean name="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
指定Trigger的名稱
<property name="name" value="hw_trigger"/>
指定Trigger的名稱
<property name="group" value="hw_trigger_group"/>
指定Tirgger綁定的Job
<property name="jobDetail" ref="hwJob"/>
指定Trigger的延遲時(shí)間 1s后運(yùn)行
<property name="startDelay" value="1000"/>
指定Trigger的重復(fù)間隔 5s
<property name="repeatInterval" value="5000"/>
指定Trigger的重復(fù)次數(shù)
<property name="repeatCount" value="5"/>
</bean> -->
<!-- 2.2:定義觸發(fā)器的bean,定義一個(gè)Cron的Trigger,一個(gè)觸發(fā)器只能和一個(gè)任務(wù)進(jìn)行綁定 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 指定Trigger的名稱 -->
<property name="name" value="hw_trigger"/>
<!-- 指定Trigger的名稱 -->
<property name="group" value="hw_trigger_group"/>
<!-- 指定Tirgger綁定的Job -->
<property name="jobDetail" ref="hwJob"/>
<!-- 指定Cron 的表達(dá)式 ,當(dāng)前是每隔1s運(yùn)行一次 -->
<property name="cronExpression" value="0/1 * * * * ?" />
</bean>
<!-- 3.定義調(diào)度器,并將Trigger注冊(cè)到調(diào)度器中 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- <ref bean="simpleTrigger"/> -->
<ref bean="cronTrigger"/>
</list>
</property>
<!-- <property name="autoStartup" value="true" /> -->
</bean>
</beans>
三、整合
1.項(xiàng)目基礎(chǔ)
項(xiàng)目是基于Spring Boot2.x版本的。

2.添加依賴
<!-- quartz依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
3.yml配置

application-quartz.yml的配置內(nèi)容如下
spring:
quartz:
#相關(guān)屬性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#數(shù)據(jù)庫(kù)方式
job-store-type: jdbc
#初始化表結(jié)構(gòu)
#jdbc:
#initialize-schema: never
4.創(chuàng)建任務(wù)測(cè)試類
簡(jiǎn)單任務(wù)

代碼如下:
public class MyJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("start My Job:" + LocalDateTime.now());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end My Job:" + LocalDateTime.now());
}
}
CRON任務(wù)

public class MyCronJob extends QuartzJobBean {
@Autowired
IndexController indexController;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("任務(wù)執(zhí)行了" + new Date());
// indexController.testMail();
}
}
5.Java配置(QuartzConfiguration)
@Configuration
public class QuartzConfiguration {
// 使用jobDetail包裝job
@Bean
public JobDetail myJobDetail() {
return JobBuilder.newJob(MyJob.class).withIdentity("myJob").storeDurably().build();
}
// 把jobDetail注冊(cè)到trigger上去
@Bean
public Trigger myJobTrigger() {
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(15).repeatForever();
return TriggerBuilder.newTrigger()
.forJob(myJobDetail())
.withIdentity("myJobTrigger")
.withSchedule(scheduleBuilder)
.build();
}
// 使用jobDetail包裝job
@Bean
public JobDetail myCronJobDetail() {
return JobBuilder.newJob(MyCronJob.class).withIdentity("myCronJob").storeDurably().build();
}
// 把jobDetail注冊(cè)到Cron表達(dá)式的trigger上去
@Bean
public Trigger CronJobTrigger() {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(myCronJobDetail())
.withIdentity("myCronJobTrigger")
.withSchedule(cronScheduleBuilder)
.build();
}
}
其實(shí)上面的配置就等價(jià)于在傳統(tǒng)的xml中配置bean是一樣的。
6.啟動(dòng)測(cè)試

至此,SpringBoot集成Quartz的完畢。
四、總結(jié)
Spring Boot集成quartz還是比較簡(jiǎn)單的。
其實(shí)還有更高級(jí)的用法,就是前臺(tái)動(dòng)態(tài)創(chuàng)建和控制定時(shí)任務(wù),后面有時(shí)間再完善。大家先把這種最簡(jiǎn)單的基本用法熟練掌握。


源碼
https://github.com/gyoomi/framework
- end -
用心分享面試知識(shí),做有溫度的攻城獅
每天記得對(duì)自己說(shuō):你是最棒的!
往期推薦:
超經(jīng)典的 25 道 MyBatis 面試題! 面試官問(wèn):前后端分離項(xiàng)目,有什么優(yōu)缺點(diǎn)? 基于SpringBoot 的CMS系統(tǒng),拿去開(kāi)發(fā)企業(yè)官網(wǎng)真香 每一個(gè)“好看”,都是對(duì)我們最大的幫助

