1 Quartz簡介
Quartz是執行定時任務的框架,由開源組織OpenSymphony在Job scheduling領域的開源項目,完全由java開發.
組成:
- Job,JobDetail
Job具體的業務邏輯類,JobDetail業務實例,實現多任務. - Trigger
JobDetail觸發器,即執行任務的觸發條件(設定的時間,時間間隔和執行次數).包括SimpleTrigger和CronTrigger,SimpleTrigger爲簡單觸發條件,如執行時間和執行次數,CronTrigger可進一步設定執行週期,年月日時段. - Scheduler
調度器,通過觸發器執行業務.
2 組件功能
2.1 Job
Job是Quartz中的一個接口,只有execute方法,在這個方法中編寫業務邏輯.
public interface Job{
void execute(JobExecutionContext var1) throws JobExecutionException;
}
2.2 JobDetail
可理解爲Job的實例,每調用一個Job,通過JobDetail創建一個新的實例,Scheduler對JobDetail進行調度,可實現多定時任務.
- JobBuilder
實例化JobDetail,創建新的Job執行任務.
2.3 JobExecutionContext
包含Job的詳細參數,當Scheduler執行一個Job時,將JobExecutionContext傳遞給Job中的execute方法.
2.4 Trigger
觸發器,滿足觸發器條件,執行任務.
- TriggerBuilder
實例化觸發器. - SimpleTrigger
觸發時間規則設定器,包括指定時間段內執行任務的次數. - CronTrigger
觸發時間規則設定器,基於日曆的作業調度,可指定執行日期,日曆規則:
秒 分 小時 日 月 周 年
序號 | 時間字段 | 允許值 | 允許特殊字符 |
---|---|---|---|
1 | 秒 | 0-59 | -*/ |
2 | 分 | 0-59 | -*/ |
3 | 小時 | 0-23 | -*/ |
4 | 日 | 1-31 | -*?/LWC |
5 | 月份 | 1-12或JAN-DEC | -*/ |
6 | 周 | 1-7或SUN-SAT | -*?/LC# |
7 | 年 | (可選)1970-2099 | -*/ |
3 Usage
3.1 pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
3.2 定時任務操作
package com.prjname.service;
import java.util.Map;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(rollbackFor = Exception.class)
public class TimerService{
@Autowired
private Scheduler scheduler;
public String buildTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
String timeCycle = taskInfos.get("taskTimeCycle").toString();
String classNameStr = taskInfos.get("className").toString();
Class className = Class.forName(classNameStr);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(timeCycle);
JobDetail jobDetail = JobBuilder.newJob(className)
.withIdentity(name, group)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(name, group)
.startNow()
.withSchedule(scheduleBuilder)
.build();
scheduler.scheduleJob(jobDetail, trigger);
return "新建並啓動5秒的定時任務";
}
public String pauseTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if(jobDetail == null){
return "定時任務不存在";
}
scheduler.pauseJob(jobKey);
return "暫停定時任務"+name;
}
public String resumeTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
JobKey jobKey= new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if(jobDetail == null){
return "定時任務不存在";
}
scheduler.resumeJob(jobKey);
return "恢復定時任務:"+name;
}
public String deleteTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if(jobDetail == null){
return "定時任務不存在";
}
scheduler.deleteJob(jobKey);
return "刪除定時任務:"+name;
}
}
3.2.1 新建定時任務
public String buildTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
String timeCycle = taskInfos.get("taskTimeCycle").toString();
String classNameStr = taskInfos.get("className").toString();
Class className = Class.forName(classNameStr);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(timeCycle);
JobDetail jobDetail = JobBuilder.newJob(className)
.withIdentity(name, group)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(name, group)
.startNow()
.withSchedule(scheduleBuilder)
.build();
scheduler.scheduleJob(jobDetail, trigger);
return "新建並啓動5秒的定時任務";
}
3.2.2 停止定時任務
public String pauseTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if(jobDetail == null){
return "定時任務不存在";
}
scheduler.pauseJob(jobKey);
return "暫停定時任務"+name;
}
3.2.3 重啓定時任務
public String resumeTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
JobKey jobKey= new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if(jobDetail == null){
return "定時任務不存在";
}
scheduler.resumeJob(jobKey);
return "恢復定時任務:"+name;
}
3.2.4 刪除定時任務
public String deleteTimerTask(Map taskInfos) throws Exception{
String name = taskInfos.get("taskName").toString();
String group = taskInfos.get("taskGroup").toString();
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if(jobDetail == null){
return "定時任務不存在";
}
scheduler.deleteJob(jobKey);
return "刪除定時任務:"+name;
}
3.2.5 定時任務傳參
新建定時任務時,可以傳遞參數,使用usingJobData屬性,操作如下:
JobDetail jobDetail = JobBuilder.newJob(className)
.withIdentity(name, group)
.usingJobData("params", params)
.build();
3.3 定時任務執行業務邏輯
該部分爲定時任務定期執行的業務邏輯,本次以打印時間爲例,每隔5秒,打印一次當前時間。
package com.prjname.timer;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class TestTimer extends QuartzJobBean{
static Logger logger = LoggerFactory.getLogger(TestTimer.class);
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String time = sdf.format(date);
logger.info("定時時間:{}",time);
}
}
3.4 控制器
package com.prjname.controller;
import com.xhwl.service.TimerService;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin(origins="*", maxAge=3600)
@RestController
@RequestMapping("/api/v1")
public class TimerController{
static Logger logger = LoggerFactory.getLogger(TimerController.class);
@Autowired
private TimerService timerService;
@RequestMapping(value="/timer-task-creation", method=RequestMethod.POST)
public Map createTimerTask(@RequestBody Map params){
Map returnMap = new HashMap();
try{
String taskName = params.get("taskName").toString();
String taskGroup = params.get("taskGroup").toString();
String taskTimeCycle = params.get("taskCycle").toString();
if(!taskName.equals("")|!taskGroup.equals("")|!taskTimeCycle.equals("")){
Map<String, String> taskInfos = new HashMap<String, String>();
taskInfos.put("taskName", taskName);
taskInfos.put("taskGroup", taskGroup);
taskInfos.put("taskTimeCycle", taskTimeCycle);
taskInfos.put("className", "com.prjname.timer.TestTimer");
String returnStr = timerService.startTimerTask(taskInfos);
returnMap.put("code",200);
returnMap.put("infos",returnStr);
return returnMap;
}else{
returnMap.put("code",200);
returnMap.put("infos","檢查參數");
return returnMap;
}
}catch(Exception e){
e.printStackTrace();
}
returnMap.put("code",400);
returnMap.put("infos","檢查參數");
return returnMap;
}
@RequestMapping(value="/timer-task-pause", method=RequestMethod.POST)
public Map pauseTimerTask(@RequestBody Map params){
Map returnMap = new HashMap();
try{
String taskName = params.get("taskName").toString();
String taskGroup = params.get("taskGroup").toString();
if(!taskName.equals("")|!taskGroup.equals("")){
String returnStr = timerService.pauseTimerTask(params);
returnMap.put("code", 200);
returnMap.put("infos", returnStr);
return returnMap;
}else{
returnMap.put("code", 400);
returnMap.put("infos", "檢查參數");
return returnMap;
}
}catch(Exception e){
e.printStackTrace();
}
return returnMap;
}
}
【參考文獻】
[1]https://www.jb51.net/article/160555.htm
[2]https://blog.csdn.net/noaman_wgs/article/details/80984873
[3]https://www.jianshu.com/p/056281e057b3
[4]https://www.cnblogs.com/knowledgesea/p/4705796.html
[5]https://www.cnblogs.com/bevis-byf/p/10087032.html