在項目應用中每每會用到任務定時器的功能,好比某某時間,或者多少多少秒而後執行某個騷操做等。
spring 支持多種定時任務的實現,其中不乏自身提供的定時器。
接下來介紹一下使用 spring 的定時器和使用 quartz 定時器。 css
spring 自身提供了定時任務,爲何還要使用 quartz 呢?java
使用 spring 自帶的定時任務能夠很簡單很方便的完成一些簡單的定時任務,沒錯,這裏提到的是簡單,所以咱們想動態的執行咱們的定時任務是很是困難的。然而使用 quartz 卻能夠很容易的管理咱們的定時任務,很容易動態的操做定時任務。spring
spring 自帶支持定時器的任務實現,其可經過簡單配置來使用到簡單的定時任務。數據庫
@Component
@Configurable
@EnableScheduling
public class ScheduledTasks{
/**
* 方式一
* 每6秒執行一次
**/
@Scheduled(fixedRate = 6000)
public void reportCurrentByCron(){
System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));
}
/**
* 方式二
* 每6秒執行一次
**/
@Scheduled(cron = "*/6 * * * * * ")
public void reportCurrentByCron(){
System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));
}
}
@Scheduled 參數能夠接受兩種定時的設置,一種是咱們經常使用的 cron="/6 * * * ?",一種是 fixedRate = 6000,兩種均可表示固定週期執行定時任務。微信
fixedRate說明app
cron說明框架
cron 必定有七位數,最後一位是年,SpringBoot 定時方案只須要設置六位便可:ide
cron中,還有一些特殊的符號,含義以下:spring-boot
舉幾個例子熟悉一下:工具
ok,spring的定時器就像如上這麼簡單,涉及到的幾個註解:
@EnableScheduling:標註啓動定時任務。
@Scheduled: 定義某個定時任務。
quartz 的設計者作了一個設計選擇來從調度分離開做業。
quartz 中的觸發器用來告訴調度程序做業何時觸發,框架提供了一把觸發器類型,但兩個最經常使用的是 SimpleTrigger 和 CronTrigger。
SimpleTrigger 爲須要簡單打火調度而設計。典型地,若是你須要在給定的時間和重複次數或者兩次打火之間等待的秒數打火一個做業,那麼SimpleTrigger適合你。
另外一方面,若是你有許多複雜的做業調度,那麼或許須要CronTrigger。
什麼是複雜調度?
當你須要在除星期六和星期天外的天天上午10點半執行做業時,那麼應該使用CronTrigger。正如它的名字所暗示的那樣,CronTrigger是基於Unix克隆表達式的。
開始以前須要瞭解的幾個概念:
上邊的四個概念,建議通讀一遍,結合下方代碼,思路更清晰。
SpringBoot2.x 以後,完成了對 Quartz 自動化配置集成,省去了不少繁瑣的配置,下面進入正題吧。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
spring:
quartz:
# 任務信息存儲至?MEMORY(內存方式:默認)、JDBC(數據庫方式)
job-store-type: jdbc
properties:
org:
quartz:
jobStore:
misfireThreshold: 100
/**
* @author niceyoo
*/
@Slf4j
@RestController
@Api(description = "定時任務管理接口")
@RequestMapping("/tmax/quartzJob")
public class TmaxQuartzJobController {
/**
* 定時任務service
*/
@Autowired
private QuartzJobService quartzJobService;
/**
* 調度器
*/
@Autowired
private Scheduler scheduler;
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ApiOperation(value = "添加定時任務")
public Result<Object> addJob(@ModelAttribute QuartzJob job){
add(job.getJobClassName(),job.getCronExpression(),job.getParameter());
quartzJobService.save(job);
return new ResultUtil<Object>().setSuccessMsg("建立定時任務成功");
}
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@ApiOperation(value = "更新定時任務")
public Result<Object> editJob(@ModelAttribute QuartzJob job){
delete(job.getJobClassName());
add(job.getJobClassName(),job.getCronExpression(),job.getParameter());
job.setStatus(CommonConstant.STATUS_NORMAL);
quartzJobService.update(job);
return new ResultUtil<Object>().setSuccessMsg("更新定時任務成功");
}
@RequestMapping(value = "/pause", method = RequestMethod.POST)
@ApiOperation(value = "暫停定時任務")
public Result<Object> pauseJob(@ModelAttribute QuartzJob job){
try {
scheduler.pauseJob(JobKey.jobKey(job.getJobClassName()));
} catch (SchedulerException e) {
throw new TmaxException("暫停定時任務失敗");
}
job.setStatus(CommonConstant.STATUS_DISABLE);
quartzJobService.update(job);
return new ResultUtil<Object>().setSuccessMsg("暫停定時任務成功");
}
@RequestMapping(value = "/resume", method = RequestMethod.POST)
@ApiOperation(value = "恢復定時任務")
public Result<Object> resumeJob(@ModelAttribute QuartzJob job){
try {
scheduler.resumeJob(JobKey.jobKey(job.getJobClassName()));
} catch (SchedulerException e) {
throw new TmaxException("恢復定時任務失敗");
}
job.setStatus(CommonConstant.STATUS_NORMAL);
quartzJobService.update(job);
return new ResultUtil<Object>().setSuccessMsg("恢復定時任務成功");
}
@RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
@ApiOperation(value = "刪除定時任務")
public Result<Object> deleteJob(@PathVariable String[] ids){
for(String id:ids){
QuartzJob job = quartzJobService.get(id);
delete(job.getJobClassName());
quartzJobService.delete(job);
}
return new ResultUtil<Object>().setSuccessMsg("刪除定時任務成功");
}
/**
* 添加定時任務
* @param jobClassName
* @param cronExpression
* @param parameter
*/
public void add(String jobClassName, String cronExpression, String parameter){
try {
##啓動調度器
scheduler.start();
##構建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
.withIdentity(jobClassName)
.usingJobData("parameter", parameter)
.build();
##表達式調度構建器(即任務執行的時間) 使用withMisfireHandlingInstructionDoNothing() 忽略掉調度暫停過程當中沒有執行的調度
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
##按新的cronExpression表達式構建一個新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName)
.withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
log.error(e.toString());
throw new TmaxException("建立定時任務失敗");
} catch (Exception e){
throw new TmaxException("後臺找不到該類名任務");
}
}
/**
* 刪除定時任務
* @param jobClassName
*/
public void delete(String jobClassName){
try {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
scheduler.deleteJob(JobKey.jobKey(jobClassName));
} catch (Exception e) {
throw new TmaxException("刪除定時任務失敗");
}
}
public static Job getClass(String classname) throws Exception {
Class<?> class1 = Class.forName(classname);
return (Job)class1.newInstance();
}
}
@Slf4j
public class SampleJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info(String.format("打印時間:"+ DateUtil.now()));
}
}
4小步代碼看完後,咱們再來分析一波 quartz 的4個核心概念,先腦補一張圖。
主要看 TmaxQuartzJobController 的 add() 方法
最後,調用 Controller 層的任務添加方法 /add 完成所有,效果以下:
2019-05-23 00:38:38.455 INFO 19856 --- [eduler_Worker-1] club.sscai.tmax.quartz.jobs.SampleJob : 打印時間:2019-05-24 09:38:38
2019-05-23 00:38:39.035 INFO 19856 --- [eduler_Worker-2] club.sscai.tmax.quartz.jobs.SampleJob : 打印時間:2019-05-24 09:38:39
2019-05-23 00:38:40.752 INFO 19856 --- [eduler_Worker-3] club.sscai.tmax.quartz.jobs.SampleJob : 打印時間:2019-05-24 09:38:40
2019-05-23 00:38:41.033 INFO 19856 --- [eduler_Worker-4] club.sscai.tmax.quartz.jobs.SampleJob : 打印時間:2019-05-24 09:38:41
2019-05-23 00:38:42.640 INFO 19856 --- [eduler_Worker-5] club.sscai.tmax.quartz.jobs.SampleJob : 打印時間:2019-05-24 09:38:42
2019-05-23 00:38:43.023 INFO 19856 --- [eduler_Worker-6] club.sscai.tmax.quartz.jobs.SampleJob : 打印時間:2019-05-24 09:38:43
習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:niceyoo