SpringBoot整合Quartz方法詳解
為了方便你的學(xué)習(xí)
代碼地址:Chengyunlai/Quartz_learn: SpringBoot + Quartz定時(shí)任務(wù) (github.com)
基礎(chǔ)依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> <version>2.5.2</version> </dependency>
Quartz是單應(yīng)用工程中用的比較多的定時(shí)任務(wù)框架。該定時(shí)任務(wù)主要可以分為:
- 在內(nèi)存中的任務(wù):一般定義在工程內(nèi)部存儲(chǔ),如果工程重啟后,若該任務(wù)非自動(dòng)執(zhí)行的,則不會(huì)再開(kāi)啟。
- 可持久化的任務(wù):將任務(wù)的特性存儲(chǔ)在數(shù)據(jù)庫(kù)中,工程重啟后可以重新讀取原先正在執(zhí)行的任務(wù),繼續(xù)執(zhí)行。
cron表達(dá)式
corn
是用來(lái)控制任務(wù)觸發(fā)的時(shí)刻。
我列舉一些常用的:
- 每秒鐘觸發(fā)
"* * * * * *":
- 每隔5秒執(zhí)行一次
*/5 * * * * ?
- 每分鐘觸發(fā)
"0 * * * * ?"
- 每一小時(shí)觸發(fā)
"0 * * * * ?"
- 每天10點(diǎn)觸發(fā)一次
"0 0 10 * * ?"
- 每天0點(diǎn)觸發(fā)一次
"0 0 0 * * ?"
通用
需要在啟動(dòng)類上加上@EnableScheduling
注解。
內(nèi)存任務(wù)
工程啟動(dòng)時(shí)就在執(zhí)行的任務(wù)
直接定義一個(gè)執(zhí)行任務(wù),例如:
每秒都輸出測(cè)試
@Service public class ScheduleTest { @Scheduled(cron = "0/1 * * * * *") public void test() { System.out.println("測(cè)試"); } }
啟動(dòng)類:
@SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
啟動(dòng)后看控制臺(tái)中就會(huì)輸出相應(yīng)的內(nèi)容。
手動(dòng)控制某個(gè)任務(wù)
這里需要我們自己定義任務(wù)。
定義任務(wù)
通過(guò)實(shí)現(xiàn)Job
接口,即可定義一個(gè)任務(wù),并且我們可以手動(dòng)去控制這個(gè)任務(wù)的開(kāi)啟。
public class SimpleJob implements Job { @Override public void execute(JobExecutionContext context) { System.out.println("自定義任務(wù)"); } }
借助Web-Controller去開(kāi)啟該任務(wù)
導(dǎo)入依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.6.RELEASE</version> </dependency>
編寫(xiě)Controller,這是一個(gè)固定的寫(xiě)法。
- 指定任務(wù):
JobBuilder.newJob(任務(wù).class) .withIdentity(任務(wù)名, 任務(wù)組).build();
- 指定cron表達(dá)式,創(chuàng)建Trigger:
CronScheduleBuilder.cronSchedule(cron表達(dá)式);
TriggerBuilder.newTrigger().withIdentity(啟動(dòng)器的名字, 啟動(dòng)器的分組) .withSchedule(cron).build();
- 調(diào)用任務(wù):
scheduler.scheduleJob(任務(wù)類型對(duì)象, 啟動(dòng)器對(duì)象)
/** * @ClassName * @Description * @Author:chengyunlai * @Date * @Version 1.0 **/ @RestController public class DynamicScheduleController { @Autowired private Scheduler scheduler; @GetMapping("/addSchedule") public String addSchedule() throws SchedulerException { int random = ThreadLocalRandom.current().nextInt(1000); // 1. 創(chuàng)建JobDetail,指定定時(shí)任務(wù)實(shí)現(xiàn)類的類型 JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class) .withIdentity("test-schedule" + random, "test-group").build(); // 2. 創(chuàng)建Trigger,并指定每3秒執(zhí)行一次 CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0/3 * * * * ?"); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test-trigger" + random, "test-trigger-group") .withSchedule(cron).build(); // 3. 調(diào)度任務(wù) scheduler.scheduleJob(jobDetail, trigger); return "success"; }
通過(guò)瀏覽器輸入項(xiàng)目的地址,一般默認(rèn)是localhost:8080/addSchedule
,輸入后即可看到控制臺(tái)輸出了任務(wù)執(zhí)行的輸出內(nèi)容。
持久化
如果工程重啟了,上面的SimpleJob
這個(gè)定時(shí)任務(wù)并不會(huì)重新啟動(dòng)。解決的辦法就是將任務(wù)持久化,Quartz
提供了解決方案,SpringBoot簡(jiǎn)化了這個(gè)操作。我們只需要配置好:數(shù)據(jù)庫(kù)、數(shù)據(jù)源、操作數(shù)據(jù)庫(kù)的JDBC即可。
依賴:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency>
- 使用mysql數(shù)據(jù)庫(kù):導(dǎo)入它的驅(qū)動(dòng),mysql-connector-java。
- 使用Druid作為我們的數(shù)據(jù)源:druid。
- 使用spring-jdbc,幫助我們自動(dòng)將任務(wù)信息存入到數(shù)據(jù)庫(kù)中。
配置
# 設(shè)置將定時(shí)任務(wù)的信息保存到數(shù)據(jù)庫(kù) spring.quartz.job-store-type=jdbc # 每次應(yīng)用啟動(dòng)的時(shí)候都初始化數(shù)據(jù)庫(kù)表結(jié)構(gòu) # 如果 spring.quartz.jdbc.initialize-schema 設(shè)置為 always 的話有個(gè)問(wèn)題:每次重啟應(yīng)用的時(shí)候,跟 Quartz 相關(guān)的表會(huì)被刪除重建! # 所以為了避免表被重復(fù)創(chuàng)建,我們可以提前創(chuàng)建表,然后將其指定為never spring.quartz.jdbc.initialize-schema=never # 數(shù)據(jù)庫(kù)配置 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/scheduled?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root
Quartz為我們準(zhǔn)備了sql數(shù)據(jù)表
官網(wǎng):Downloads (quartz-scheduler.org)
以我:quartz-2.3.0-SNAPSHOT為例子:
下載源碼后,找到jdbcjobstore
這個(gè)目錄:
quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore
然后會(huì)有一系列的sql
文件,找到和你數(shù)據(jù)庫(kù)匹配的那個(gè)sql文件即可,我用的是mysql。
執(zhí)行SQL文件建表,我的數(shù)據(jù)庫(kù)名是:scheduled
,各位從我的url中應(yīng)該也能看出來(lái)。
建表完成后,所有配置工作結(jié)束了,啟動(dòng)程序,重新在瀏覽器中輸入:localhost:8080/addSchedule
,然后刷新一下數(shù)據(jù)庫(kù),就會(huì)發(fā)現(xiàn)任務(wù)被持久化了,此時(shí)重啟工程后,該任務(wù)依舊會(huì)自動(dòng)執(zhí)行。
暫停任務(wù)和刪除任務(wù)
我們?cè)谑謩?dòng)開(kāi)啟該任務(wù)的時(shí)候會(huì)指定:
- 任務(wù)的名稱和組
JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class) .withIdentity(任務(wù)名,任務(wù)組).build();
在暫停和恢復(fù)任務(wù)時(shí),就需要用JobKey.jobKey(任務(wù)名,任務(wù)組)
,得到一個(gè)JobKey
,然后使用scheduler.pauseJob(jobkey)
即可暫停任務(wù);scheduler.resumeJob(jobKey)
恢復(fù)任務(wù)。
- 刪除任務(wù)的時(shí)候需要將任務(wù)和Trigger都刪除,而在上面我們可以拿到這個(gè)
jobkey
表示任務(wù),我們也需要拿到trigger,同樣的我們也定義過(guò)啟動(dòng)器的名字和分組。
`TriggerBuilder.newTrigger().withIdentity(啟動(dòng)器的名字, 啟動(dòng)器的分組) .withSchedule(cron).build();`
TriggerKey.triggerKey((啟動(dòng)器的名字, 啟動(dòng)器的分組);
也可以拿到trigger
表示啟動(dòng)器。
- 通過(guò)以下順序完整刪除任務(wù)
- // 停止觸發(fā)器
- scheduler.pauseTrigger(triggerKey);
- // 移除觸發(fā)器
- scheduler.unscheduleJob(triggerKey);
- // 刪除任務(wù)
- scheduler.deleteJob(jobKey);
- // 停止觸發(fā)器
// 暫停 @GetMapping("/pauseSchedule") public String pauseSchedule(String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); // 獲取定時(shí)任務(wù) JobDetail jobDetail = scheduler.getJobDetail(jobKey); if (jobDetail == null) { return "error"; } scheduler.pauseJob(jobKey); return "success"; } // 恢復(fù) @GetMapping("/remuseSchedule") public String remuseSchedule(String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); // 獲取定時(shí)任務(wù) JobDetail jobDetail = scheduler.getJobDetail(jobKey); if (jobDetail == null) { return "error"; } scheduler.resumeJob(jobKey); return "success"; } // 刪除定時(shí)任務(wù) @GetMapping("/removeSchedule") public String removeSchedule(String jobName, String jobGroup, String triggerName, String triggerGroup) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup); JobKey jobKey = JobKey.jobKey(jobName, jobGroup); Trigger trigger = scheduler.getTrigger(triggerKey); if (trigger == null) { return "error"; } // 停止觸發(fā)器 scheduler.pauseTrigger(triggerKey); // 移除觸發(fā)器 scheduler.unscheduleJob(triggerKey); // 刪除任務(wù) scheduler.deleteJob(jobKey); return "success"; }
未來(lái)
后續(xù),我準(zhǔn)備結(jié)合前端,做一個(gè)頁(yè)面的定時(shí)任務(wù)功能。
到此這篇關(guān)于SpringBoot整合Quartz方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot整合Quartz內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot?整合?Quartz?定時(shí)任務(wù)框架詳解
- SpringBoot整合Quartz實(shí)現(xiàn)定時(shí)任務(wù)詳解
- springboot創(chuàng)建的web項(xiàng)目整合Quartz框架的項(xiàng)目實(shí)踐
- springboot整合quartz實(shí)例demo
- springboot整合quartz定時(shí)任務(wù)框架的完整步驟
- Springboot整合quartz產(chǎn)生錯(cuò)誤及解決方案
- SpringBoot定時(shí)任務(wù)兩種(Spring Schedule 與 Quartz 整合 )實(shí)現(xiàn)方法
相關(guān)文章
Java實(shí)現(xiàn)json數(shù)據(jù)處理的常用腳本分享
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)json數(shù)據(jù)處理的常用腳本,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下2023-03-03idea打開(kāi)運(yùn)行配置java?web項(xiàng)目的全過(guò)程
這篇文章主要給大家介紹了關(guān)于idea打開(kāi)運(yùn)行配置java?web項(xiàng)目的相關(guān)資料,有些時(shí)候我們用IDEA跑之前用eclipse中運(yùn)行的項(xiàng)目的時(shí)候,總是不止所措,要不就是只展示html,要不就是不能部署成功,需要的朋友可以參考下2023-08-08一文搞懂MyBatis多數(shù)據(jù)源Starter實(shí)現(xiàn)
本文將實(shí)現(xiàn)一個(gè)MyBatis的Springboot的Starter包,引用這個(gè)Starter包后,僅需要提供少量配置信息,就能夠完成MyBatis多數(shù)據(jù)源的初始化和使用,需要的小伙伴可以參考一下2023-04-04Java方法覆蓋重寫(xiě)實(shí)現(xiàn)原理解析
這篇文章主要介紹了Java方法覆蓋重寫(xiě)實(shí)現(xiàn)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12SpringBoot整合MyCat實(shí)現(xiàn)讀寫(xiě)分離的方法
這篇文章主要介紹了SpringBoot整合MyCat實(shí)現(xiàn)讀寫(xiě)分離的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04