需要声明的是,本篇博客参考了springboot整合Quartz实现动态配置定时任务和 spring boot整合quartz实现多个定时任务。其中的大部分代码都是参考这两篇博客中的代码。在此感谢博主! 因为项目中需要用到比较复杂的定时,就看了下quartz。参考了上面的两篇博客,算是个demo吧。 简单理解,quartz的定时可以大致分为两部分,一种时单任务,一种是多任务。 需要引入的依赖:
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> 12345添加一个任务:
@Configuration @Component @EnableScheduling // 该注解必须要加 public class ScheduleTask { public void scheduleTest() { System.err.println("scheduleTest开始定时执行"); } } 12345678配置:
@Configuration public class QuartzConfigration { @Bean(name = "jobDetail") public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) { // ScheduleTask为需要执行的任务 MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); /* * 是否并发执行 * 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了, * 如果此处为true,则下一个任务会bing执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行 */ jobDetail.setConcurrent(true); jobDetail.setName("scheduler");// 设置任务的名字 jobDetail.setGroup("scheduler_group");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 /* * 这两行代码表示执行task对象中的scheduleTest方法。定时执行的逻辑都在scheduleTest。 */ jobDetail.setTargetObject(task); jobDetail.setTargetMethod("scheduleTest"); return jobDetail; } @Bean(name = "jobTrigger") public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) { CronTriggerFactoryBean tigger = new CronTriggerFactoryBean(); tigger.setJobDetail(jobDetail.getObject()); tigger.setCronExpression("0/6 * * * * ?");// 表示每隔6秒钟执行一次 //tigger.set tigger.setName("myTigger");// trigger的name return tigger; } @Bean(name = "scheduler") public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) { SchedulerFactoryBean bean = new SchedulerFactoryBean(); //设置是否任意一个已定义的Job会覆盖现在的Job。默认为false,即已定义的Job不会覆盖现有的Job。 bean.setOverwriteExistingJobs(true); // 延时启动,应用启动5秒后 ,定时器才开始启动 bean.setStartupDelay(5); // 注册定时触发器 bean.setTriggers(cronJobTrigger); return bean; } //多任务时的Scheduler,动态设置Trigger。一个SchedulerFactoryBean可能会有多个Trigger @Bean(name = "multitaskScheduler") public SchedulerFactoryBean schedulerFactoryBean(){ SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); return schedulerFactoryBean; } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455项目启动5秒后,定时器开始启动。 截图如下:
在Controller中动态改变tigger表达式:
@Controller public class QuartzController { @Resource(name = "jobDetail") private JobDetail jobDetail; @Resource(name = "jobTrigger") private CronTrigger cronTrigger; @Resource(name = "scheduler") private Scheduler scheduler; /* @Resource(name="haha") private UseFunctionService useFunctionService; @Resource private FunctionDao functionDao;*/ @ResponseBody @RequestMapping("/{prod}/quart") public String quartzTest(@PathVariable Integer prod) throws SchedulerException{ CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); String currentCron = trigger.getCronExpression();// 当前Trigger使用的 System.err.println("当前trigger使用的-"+currentCron); //1秒钟执行一次 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?"); // 按新的cronExpression表达式重新构建trigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()) .withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(cronTrigger.getKey(), trigger); return prod+"-这是quartz测试"; } } 12345678910111213141516171819202122232425262728293031323334在浏览器中访问该controller后,scheduleTest方法1秒钟执行一次。
总结:quartz执行单任务,需要自定义一个Task类并将定时执行的逻辑写在方法里面。MethodInvokingJobDetailFactoryBean中配置任务的名字和分组,设置定时执行逻辑的对象和方法。CronTriggerFactoryBean中配置MethodInvokingJobDetailFactoryBean的实例以及定时表达式。SchedulerFactoryBean设置启动时机,注册触发器(即为Trigger对象)。
quartz多任务需要用到Job类,将定时的逻辑写在Job类中。 定义两个Job表示两个任务:
public class ScheduledJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.err.println("这是第一个任务 is running…………………………………… "); } } 12345678910 public class ScheduledJob2 implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.err.println("第二个任务正在运行 is running…………………………………… "); } } 12345678910在Controller中启动定时任务:
@Controller public class QuartzController { @Resource(name="multitaskScheduler") private Scheduler scheduler2; @ResponseBody @RequestMapping("/multitask") public String multitask() throws SchedulerException { scheduleJob2(scheduler2); return "多任务"; } @ResponseBody @RequestMapping("/multitask2") public String multitask2() throws SchedulerException { scheduleJob(scheduler2); return "这个也是多任务"; } //具体的定时任务 private void scheduleJob2(Scheduler scheduler) throws SchedulerException{ //配置定时任务对应的Job,这里执行的是ScheduledJob类中定时的方法 JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class) .withIdentity("job2", "group1").build(); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?"); // 每3s执行一次 CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1") .withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); } private void scheduleJob(Scheduler scheduler) throws SchedulerException{ //配置定时任务对应的Job,这里执行的是ScheduledJob2类中定时的方法 JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class) .withIdentity("job1", "group1").build(); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/6 * * * * ?"); // 每6s执行一次 CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") .withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546执行效果如下图: 总结:quartz多任务,有多少任务就有多少个Job。 关于cronExpression表达式,可以参考这篇文章,说得很清楚,感谢博主。cronExpression参考文章
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/production/markdown_views-ea0013b516.css"> </div>