目录
3.4任务执行时上下文(JobExecutionContext)
1.定时任务实现的方式
- Timer和TimerTask
- ScheduledExecutorService
- 三方框架 Quartz
- springboot注解实现(@EnableScheduling、@Scheduled)
2.CronExpression表达式
CronExpressionhttps://blog.csdn.net/m0_48983233/article/details/122656494
3.Quqrtz实现定时任务
3.1任务/作业(Task/Job)
位于org.quartz.Job的接口,是quartz中的核心任务接口,要实现自定义的定时任务(就是我们要执行的业务动作/作业)只需要实现此接口。也可以继承实现类QuartzJobBean。重新里面的executeInternal(JobExecutionContext jobExecutionContext)方法。
3.2触发器(Trigger)
位于org.quartz.Trigger,触发器用来告诉调度程序作业什么时候触发,也就是我们要设置任务触发的条件。quartz提供了5种触发器类型,但两个最常用的SimpleTrigger和CronTrigger。
五种类型的Trigger(触发器):
SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar。
3.3调度器(Schedule)
来自org.quartz.Schedule是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册,调度器负责执行作业,当他们的相关联的触发器触发时(当他们的预定时间到达时)。不难看出功能就是将任务job与触发器Trigger作业结合起来
3.4任务执行时上下文(JobExecutionContext)
位于org.quartz.JobExecutionContext的类,是任务在执行时quartz注入的对象,用于保存任务的详细信息(比如触发器,调度器,工作详情,任务入参等),我们可以通过此对象得到运行时的任务数据,也可以接受动态参数。
3.5.任务详情(JobDetail)
位于org.quartz.JobDetail,用来绑定job,为job提供一些属性:
- name:唯一标识
- group:分组标识
- jobClass:具体任务
- jobDataMap:任务入参
为什么设计成JobDetail + Job,不直接使用Job?
JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。
这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。
3.6应用Demo
Task:
public class QuartzTask extends QuartzJobBean {
// 这种可以注入
@Autowired
private QuartzTaskController quartzTaskController;
// 这里不能注入Controller ?????
/*@Autowired 这里不能注入Controller
public QuartzTask(QuartzTaskController quartzTaskController) {
this.quartzTaskController = quartzTaskController;
}*/
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
this.quartzTaskController.updateVectorParcelNumber();
}
}
简单任务配置:
@Configuration
public class QuzrtzTaskConfiguration {
@Value("${cron}")
private String cron;
@Bean
public JobDetail getSimpleJobDetail() {
return JobBuilder.newJob(QuartzTask.class)
.storeDurably()
.build();
}
@Bean
public Trigger getSimpleTrigger() {
SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
simpleScheduleBuilder.withIntervalInMinutes(20)
.repeatForever();
return TriggerBuilder.newTrigger()
.forJob(getSimpleJobDetail())
.withIdentity("testSimpleScheduleBuilder")
.withSchedule(simpleScheduleBuilder)
.startNow() // 立即执行定时任务
.build();
}
}
Cron表达式任务配置:
@Configuration
public class QuzrtzTaskConfiguration {
@Value("${cron}")
private String cron;
/**
* 使用JobDetail包装Job
* @return
*/
@Bean
public JobDetail getCronJobDetail() {
return JobBuilder.newJob(QuartzTask.class)
.withIdentity("ModifyVectorParcelNumberTask")
.storeDurably()
.build();
}
/**
* 把JobDetail注册到cron表达式的trigger上去
* @return
*/
@Bean
public Trigger getCronTrigger() {
//CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 59/10 * * * ? *");
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(this.cron);
return TriggerBuilder.newTrigger()
.forJob(getCronJobDetail())
.withIdentity("testCronScheduleBuild")
.withSchedule(cronScheduleBuilder)
//.startNow() StartNow 应该只适用于 SimpleTrigger 触发器。
.build();
}
}