需要声明的是,本篇博客参考了springboot整合Quartz实现动态配置定时任务和 spring boot整合quartz实现多个定时任务。其中的大部分代码都是参考这两篇博客中的代码。在此感谢博主!
因为项目中需要用到比较复杂的定时,就看了下quartz。参考了上面的两篇博客,算是个demo吧。
简单理解,quartz的定时可以大致分为两部分,一种时单任务,一种是多任务。
需要引入的依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
1,quartz单任务
添加一个任务:
@Configuration
@Component
@EnableScheduling // 该注解必须要加
public class ScheduleTask {
public void scheduleTest() {
System.err.println("scheduleTest开始定时执行");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
配置:
@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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
项目启动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测试";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
在浏览器中访问该controller后,scheduleTest方法1秒钟执行一次。
总结:quartz执行单任务,需要自定义一个Task类并将定时执行的逻辑写在方法里面。MethodInvokingJobDetailFactoryBean中配置任务的名字和分组,设置定时执行逻辑的对象和方法。CronTriggerFactoryBean中配置MethodInvokingJobDetailFactoryBean的实例以及定时表达式。SchedulerFactoryBean设置启动时机,注册触发器(即为Trigger对象)。
2,quartz多任务
quartz多任务需要用到Job类,将定时的逻辑写在Job类中。
定义两个Job表示两个任务:
public class ScheduledJob implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.err.println("这是第一个任务 is running…………………………………… ");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
public class ScheduledJob2 implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.err.println("第二个任务正在运行 is running…………………………………… ");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
执行效果如下图:
总结:quartz多任务,有多少任务就有多少个Job。
关于cronExpression表达式,可以参考这篇文章,说得很清楚,感谢博主。cronExpression参考文章
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/production/markdown_views-ea0013b516.css">
</div>