1、分部解释
2、完整代码
3、SpringBoot定时任务+Quartz
1、动态定时任务:
- 动态定时任务,即定时任务的动态调度,可根据需求自由的进行任务的生成、暂停、恢复、删除和更新操作。
- Quartz本身没有提供动态调度的功能,需要自己根据相关的API开发。
2、动态定时任务使用场景:
- 订单成功后自动发短信通知
- 每日推送的功能引发用户不满,不再定时推送
- 每日下班前30分钟发送工作报表,遇节假日暂停发送
- …
3、Scheduler调度器常用API
4、实现动态调度的定时任务
注释:
JobBean:封装,任务调度的参数,不在使用默认的调度方式。
代码演示:
1、JobBean 类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JobBean {//任务名字private String jobName;//任务类,(自己任务,实现类的全类名) --->任务类.class.getName()private String jobClass;//cron表达式private String cronExpression;
}
2、创建一个工具类:
2.1、创建定时任务:
//创建任务public static void createJob(Scheduler scheduler, JobBean jobBean) {//通过类的名字获取类Class<? extends Job> jobClass = null;CronTrigger trigger =null;JobDetail jobDetail =null;try {jobClass = (Class<? extends Job>) Class.forName(jobBean.getJobClass());jobDetail = JobBuilder.newJob(jobClass).storeDurably()//唯一标识.withIdentity(jobBean.getJobName()).build();//创建触发器trigger = TriggerBuilder.newTrigger().forJob(jobDetail)//唯一标识和上面的JobDetail是配对的。当然写别的名称也是可以的,就是一个标识.withIdentity(jobBean.getJobName())//这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。//每两秒钟执行一次.withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression())).build();//需要 JobDetail var1, Trigger var2 这两个参数scheduler.scheduleJob(jobDetail, trigger);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}catch (SchedulerException e) {throw new RuntimeException(e);}}
2.2、暂停任务:
//暂停任务public static void pauseJob(Scheduler scheduler, String jobName) {try {scheduler.pauseJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}
2.3、恢复任务:
//恢复任务public static void resumeJob(Scheduler scheduler, String jobName) {try {scheduler.resumeJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}
2.4、删除任务:
//删除任务public static void deleteJob(Scheduler scheduler, String jobName) {try {scheduler.deleteJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}
2.5、执行一次任务
//执行一次任务public static void runOnce(Scheduler scheduler, String jobName) {try {scheduler.triggerJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}
2.6、修改任务
//修改任务public static void updateJob(Scheduler scheduler, JobBean jobBean) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobBean.getJobName());//强制转换成CronTriggerCronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// oldTrigger.getTriggerBuilder(); 将老的trigger返回出来CronTrigger newTrigger = oldTrigger.getTriggerBuilder().withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression())).build();scheduler.rescheduleJob(triggerKey,newTrigger);} catch (SchedulerException e) {throw new RuntimeException(e);}}
5、编写控制器方法:
完整代码:
1、pom文件
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>
2、任务调度需要参数类(封装参数类 POJO)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JobBean {//任务名字private String jobName;//任务类,(自己任务,实现类的全类名) --->任务类.class.getName()private String jobClass;//cron表达式private String cronExpression;
}
3、工具类:
public class DynJobUtil {//创建任务public static void createJob(Scheduler scheduler, JobBean jobBean) {//通过类的名字获取类Class<? extends Job> jobClass = null;CronTrigger trigger =null;JobDetail jobDetail =null;try {jobClass = (Class<? extends Job>) Class.forName(jobBean.getJobClass());jobDetail = JobBuilder.newJob(jobClass).storeDurably()//唯一标识.withIdentity(jobBean.getJobName()).build();//创建触发器trigger = TriggerBuilder.newTrigger().forJob(jobDetail)//唯一标识和上面的JobDetail是配对的。当然写别的名称也是可以的,就是一个标识.withIdentity(jobBean.getJobName())//这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。//每两秒钟执行一次.withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression())).build();//需要 JobDetail var1, Trigger var2 这两个参数scheduler.scheduleJob(jobDetail, trigger);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}catch (SchedulerException e) {throw new RuntimeException(e);}}//暂停任务public static void pauseJob(Scheduler scheduler, String jobName) {try {scheduler.pauseJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}//恢复任务public static void resumeJob(Scheduler scheduler, String jobName) {try {scheduler.resumeJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}//删除任务public static void deleteJob(Scheduler scheduler, String jobName) {try {scheduler.deleteJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}//执行一次任务public static void runOnce(Scheduler scheduler, String jobName) {try {scheduler.triggerJob(JobKey.jobKey(jobName));} catch (SchedulerException e) {throw new RuntimeException(e);}}//修改任务public static void updateJob(Scheduler scheduler, JobBean jobBean) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobBean.getJobName());//强制转换成CronTriggerCronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// oldTrigger.getTriggerBuilder(); 将老的trigger返回出来CronTrigger newTrigger = oldTrigger.getTriggerBuilder().withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression())).build();scheduler.rescheduleJob(triggerKey,newTrigger);} catch (SchedulerException e) {throw new RuntimeException(e);}}
}
4、自己的任务
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {System.out.println("任务开始执行");JobDetail jobDetail = context.getJobDetail();System.out.println("名字" + jobDetail.getKey().getName());System.out.println("类名--->" + jobDetail.getJobClass().getName());System.out.println("本次执行的时间为---》" + context.getFireTime());System.out.println("下次执行的时间为---》" + context.getNextFireTime());System.out.println("任务执行完毕");System.out.println("============================");}
}
5、进行测试:
@Slf4j
@Controller
@RequestMapping("/job")
public class DynJob {@Autowiredprivate Scheduler scheduler;JobBean jobBean = new JobBean("jobDetail",MyJob.class.getName(),"0/5 * * * * ?");//创建任务@GetMapping("/createJob")public void createJob(){log.info("jobBean:{}",jobBean);log.info("创建任务");DynJobUtil.createJob(scheduler,jobBean);}//暂停任务@GetMapping("/pauseJob")public void pauseJob(){JobBean jobBean = new JobBean("jobDetail","jobClass","0/5 * * * * ?");log.info("jobBean:{}",jobBean);log.info("暂停任务");DynJobUtil.pauseJob(scheduler,jobBean.getJobName());}//恢复任务@GetMapping("/resumeJob")public void resumeJob(){log.info("jobBean:{}", jobBean);log.info("恢复任务");DynJobUtil.resumeJob(scheduler, jobBean.getJobName());}//删除任务@GetMapping("/deleteJob")public void deleteJob(){log.info("jobBean:{}", jobBean);log.info("删除任务");DynJobUtil.deleteJob(scheduler, jobBean.getJobName());}//执行一次任务,暂停之后就是执行一次,之后不在执行@GetMapping("/runJob")public void runJob(){log.info("jobBean:{}", jobBean);log.info("执行一次任务");DynJobUtil.runOnce(scheduler, jobBean.getJobName());}//修改任务@GetMapping("/modifyJob")public void modifyJob() {jobBean.setCronExpression("0/2 * * * * ?");log.info("jobBean:{}", jobBean);log.info("修改任务");DynJobUtil.updateJob(scheduler, jobBean);}
}