文章目录
一、Quartz核心组件及相互关系
pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
1、Job:任务。
2、JobDetail:任务详情。
3、Trigger:触发器 主要是cron的定义。
4、Scheduler:调度器 整合Job和Trigger,进行任务执行。
相互关系
Job:JobDetail -> 1:N
JobDetail:Trigger -> 1:N
Trigger:JobDetail -> 1:1
二、代码案例
1、创建Job类
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail jobDetail1 = context.getJobDetail();
System.out.println("任务名称:"+jobDetail1.getKey().getName());
System.out.println("任务组信息:"+jobDetail1.getKey().getGroup());
System.out.println("任务类信息:"+jobDetail1.getJobClass().getName());
System.out.println("本次执行时间:"+context.getFireTime());
System.out.println("下次执行时间:"+context.getNextFireTime());
//获取jobtail里面设置的共享数据
JobDataMap jobDataMap = jobDetail1.getJobDataMap();
Integer count = (Integer) jobDataMap.get("count");
System.out.println("第"+count+"次执行");
jobDataMap.put("count",++count); //将最新数据放回
}
}
2、创建JobDetail类
在config配置类中,创建
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
@Bean
public JobDetail jobDetail1(){
return JobBuilder.newJob(MyJob.class) //关联上一步的Job
.withIdentity("job1","group1") //唯一标识
.storeDurably() //持久化
.usingJobData("count",1) // 共享数据初始化
.build();
}
}
3、创建Trigger
在config配置类中,创建
@Bean
public Trigger trigger1(){
//cron表达式
String cronStr = "0/2 * * * * ? *";
return TriggerBuilder.newTrigger()
.withIdentity("trigger1","group1") //设置唯一标识
.forJob(jobDetail1()) //关联创建的JobDetail
.withSchedule(CronScheduleBuilder.cronSchedule(cronStr)) //设置cron
.build();
}
4、Scheduler无需手动创建,springboot自行管理
5、运行application,测试效果
发现,基本信息都正确
但是,共享数据,总是第1次。
6、解决共享数据问题
原因分析:从context中获取的jobDetail每次都是一个新的实例。
所以,jobDetail中的数据会被重置。
JobDetail jobDetail1 = context.getJobDetail();
System.out.println(System.identityHashCode(jobDetail1));
解决办法:
给job类,添加注解:@PersistJobDataAfterExecution
7、任务并发问题
问题描述:
就是当前任务还没有完成时,又到了任务下一次执行的时间
这样,执行任务时间上就重叠了,也就是任务并发了。
可能导致数据错乱问题。
注意:这个与并发编程不是一个问题。
现象:
解决办法:
给job类,添加注解:@DisallowConcurrentExecution
执行:
会发现,不在是2秒执行一次,是等当前任务执行完,立即执行下一次任务。所以时间间隔变成了3秒一次。
三、总结
整体的开发思路就是
先写Job类
然后,在config配置类中,通过spring容器,注入jobDetail和trigger