SpringBoot:整合quartz实现定时任务-基础篇
文章目录
- 一、Quartz核心组件及相互关系
- 二、代码案例
- 三、总结
一、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 {@Overridepublic 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 {@Beanpublic JobDetail jobDetail1(){return JobBuilder.newJob(MyJob.class) //关联上一步的Job .withIdentity("job1","group1") //唯一标识.storeDurably() //持久化.usingJobData("count",1) // 共享数据初始化.build();}
}
3、创建Trigger
在config配置类中,创建
@Beanpublic 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