SpringBoot:整合quartz实现定时任务-基础篇

发布于:2025-07-04 ⋅ 阅读:(19) ⋅ 点赞:(0)

一、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