前言:
1、定时任务技术:
- JDK 的 Timer, 定义多个定时任务,其中某个任务出现异常,当时整个定时任务终止。
- Spring Task , 不支持 持久化与分布式部署,所有任务是单线程执行的
- Quartz,支持持久化多线程执行。
2、Spring Boot 整合Quartz
- Job: 任务。定时执行的具体任务内容
- JobDetail: 任务详情。即与任务相关的其他配置信息
- Trigger: 触发器,主要负责描述任务执行的时间规则
- Scheduler: 调度器。
- 将Job和Trigger整合起来之间的关系: Job:JobDetail->1:N JobDetail:Trigger->1:N Trigger:JobDetail->1:1
3、引入pom文件:
javascript
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
4、创建执行任务,Job (自己的定时任务)
对应代码:
javascript
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {
@Override
protected 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、创建JobDtail 和 Trigger
在执行任务的类上添加注解。
- PersistJobDataAfterExecution ,有状态的,在定时任务执行的Job中获取的JobExecutionContext 是同一个。比如在JobDetail 中,usingJobData("count",1);进行共享数据的初始化,如果不使用这个注解在执行任务上,会获取不同的JobExecutionContext 。
- DisallowConcurrentExecution 在时间间隔内,如果本任务没有执行完成,下一个任务不会启动,一直到本任务结束。下一个任务才开始执行。
创建配置类:
解释:
持久化 .storeDurably() 。如果没有持久化,没有对应的触发器,失去执行的条件,存在没有意义,就会将其删除。
如果有持久化,没有对应的触发器,还是会保留 JobDetail。
对应代码:
javascript
@Configuration
public class QuartzConfiguration {
//JobDetail
@Bean(value = "jobDetail")
public JobDetail jobDetail(){
return JobBuilder.newJob(MyJob.class)
.storeDurably()
//唯一标识
.withIdentity("jobDetail")
.build();
}
@Bean
// @Qualifier 引用指定的bean 的实例对象。
public Trigger trigger(@Qualifier("jobDetail")JobDetail jobDetail){
Trigger jobDetail1 = TriggerBuilder.newTrigger()
.forJob(jobDetail)
//唯一标识和上面的JobDetail是配对的。
.withIdentity("jobDetail")
//这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
//每两秒钟执行一次
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
.build();
return jobDetail1;
}
}
6、cron表达式
java
tips:
一般使用 六位,最后一位年 一般不使用。
整体代码实例演示:
pom文件
javascript
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
1、自己的定时任务Job
javascript
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {
@Override
protected 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("============================");
}
}
2、定时任务的配置类
javascript
@Configuration
public class QuartzConfiguration {
//JobDetail
@Bean(value = "jobDetail")
public JobDetail jobDetail(){
return JobBuilder.newJob(MyJob.class)
.storeDurably()
//唯一标识
.withIdentity("jobDetail")
.build();
}
@Bean
//Trigger
public Trigger trigger(@Qualifier("jobDetail")JobDetail jobDetail){
Trigger jobDetail1 = TriggerBuilder.newTrigger()
.forJob(jobDetail)
//唯一标识和上面的JobDetail是配对的。
.withIdentity("jobDetail")
//这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
//每两秒钟执行一次
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
.build();
return jobDetail1;
}
}