Quartz 定时任务调度框架

本文介绍了如何在Java中使用Quartz框架实现定时任务,包括基本的Job和Trigger配置,有状态Job的示例,以及@PersistJobDataAfterExecution的使用。重点展示了如何在任务执行过程中读取和操作JobDataMap,以及不同类型的Job(无状态与有状态)的区别。
摘要由CSDN通过智能技术生成

Quartz 定时任务调度框架

入门案例:

  • 依赖:
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.2</version>
</dependency>
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz-jobs</artifactId>
	<version>2.3.2</version>
</dependency>
  • Job类:
package com.blu.job;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class HelloJob implements Job{

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = dateFormat.format(date);
		System.out.println("当前时间:"+dateString);
	}

}
  • 测试类:
package com.blu.test;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import com.blu.job.HelloJob;

public class HelloScheduleTest {

	public static void main(String[] args) throws Exception {
		//调度器(Scheduler),从工厂中获取
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		//任务示例(JobDetail)
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "JobGroup1").build();
		//触发器(Trigger)
		Trigger trigger = TriggerBuilder.newTrigger()
					.withIdentity("trigger1", "TriggerGroup1")
					//立即启动触发器
					.startNow()
					//每5s重复执行一次
					.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5))
					.build();
		//让调度器关联任务和触发器
		scheduler.scheduleJob(jobDetail,trigger);
		scheduler.start();
	}

}
  • 运行效果:每5s打印一次时间
当前时间:2020-10-06 19:34:09
当前时间:2020-10-06 19:34:14
当前时间:2020-10-06 19:34:19
当前时间:2020-10-06 19:34:24
当前时间:2020-10-06 19:34:29
当前时间:2020-10-06 19:34:34
当前时间:2020-10-06 19:34:39
当前时间:2020-10-06 19:34:44
当前时间:2020-10-06 19:34:49
当前时间:2020-10-06 19:34:54
当前时间:2020-10-06 19:34:59
当前时间:2020-10-06 19:35:04

扩展

  • Job类:
package com.blu.job;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Trigger;

public class HelloJob implements Job{
	
	private String message;
	
	public void setMessage(String message) {
		this.message = message;
	}

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = dateFormat.format(date);
		//获取JobDetail的内容
		JobKey jobKey = context.getJobDetail().getKey();
		System.out.println(jobKey.getName());
		System.out.println(jobKey.getGroup());
		System.out.println(context.getJobDetail().getJobClass().getName());
		//从JobDetail对象中获取JobDataMap的数据
		JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
		String jobDataMessage = jobDataMap.getString("message");
		System.out.println(jobDataMessage);
		//从Trigger对象中获取JobDataMap的数据
		JobDataMap  triggerDataMap = context.getTrigger().getJobDataMap();
		String triggerDataMessage = triggerDataMap.getString("message");
		System.out.println(triggerDataMessage);
		//获取Trigger中的内容
		Trigger trigger = context.getTrigger();
		System.out.println(trigger.getKey().getName());
		System.out.println(trigger.getKey().getGroup());
		System.out.println(trigger.getKey().getClass());
		//初始化job类示例对象时会自动调用setter方法为属性赋值
		//当trigger与JobDetail设置了重名属性时,setter方法获取的值就是trigger设置的属性值                                                                       
		System.out.println("通过setter直接获取数据:"+message);
		//获取其他内容
		System.out.println("当前任务执行时间"+dateFormat.format(context.getFireTime()));
		System.out.println("下次任务的执行时间"+dateFormat.format(context.getNextFireTime()));
		System.out.println("当前时间:"+dateString);
	}

}
  • 测试类:
package com.blu.test;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

import com.blu.job.HelloJob;

public class HelloScheduleTest {

	public static void main(String[] args) throws Exception {
		//调度器(Scheduler),从工厂中获取
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		//任务示例(JobDetail)
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
					.withIdentity("job1", "JobGroup1")
					.usingJobData("message","jobDetail传递的值")
					.build();
//		System.out.println(jobDetail.getKey().getName());
//		System.out.println(jobDetail.getKey().getGroup());
//		System.out.println(jobDetail.getKey().getClass());
		//触发器(Trigger)
		Trigger trigger = TriggerBuilder.newTrigger()
					.withIdentity("trigger1", "TriggerGroup1")
					//立即启动触发器
					.startNow()
					//每5s重复执行一次
					.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5))
					.usingJobData("message","trigger传递的值")
					.build();
		//让调度器关联任务和触发器
		scheduler.scheduleJob(jobDetail,trigger);
		scheduler.start();
	}

}
  • 运行结果
job1
JobGroup1
com.blu.job.HelloJob
jobDetail传递的值
trigger传递的值
trigger1
TriggerGroup1
class org.quartz.TriggerKey
通过setter直接获取数据:trigger传递的值
当前任务执行时间2020-10-08 13:52:33
下次任务的执行时间2020-10-08 13:52:38
当前时间:2020-10-08 13:52:33

job1
JobGroup1
com.blu.job.HelloJob
jobDetail传递的值
trigger传递的值
trigger1
TriggerGroup1
class org.quartz.TriggerKey
通过setter直接获取数据:trigger传递的值
当前任务执行时间2020-10-08 13:52:38
下次任务的执行时间2020-10-08 13:52:43
当前时间:2020-10-08 13:52:38

job1
JobGroup1
com.blu.job.HelloJob
jobDetail传递的值
trigger传递的值
trigger1
TriggerGroup1
class org.quartz.TriggerKey
通过setter直接获取数据:trigger传递的值
当前任务执行时间2020-10-08 13:52:43
下次任务的执行时间2020-10-08 13:52:48
当前时间:2020-10-08 13:52:43

@PersistJobDataAfterExecution 有状态的Job和无状态的Job:

每次执行任务时都会创建一个新的Job实例

默认的无状态Job每次调用时都会创建一个新的JobDataMap

而有状态的Job在多次Job调用期间可以在JobDataMap中存储一些状态信息

  • Job类:
package com.blu.job;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

@PersistJobDataAfterExecution
public class HiJob implements Job{
	
	private Integer count;

	public void setCount(Integer count) {
		this.count = count;
	}

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("当前时间:"+ dateFormat.format(date));
		
		//累加count,输出count,存入JobDataMap
		count++;
		System.out.println(count);
		context.getJobDetail().getJobDataMap().put("count", count);
		
	}
	
}
  • 测试类:
package com.blu.test;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

import com.blu.job.HiJob;

public class HiTest {

	public static void main(String[] args) throws Exception {
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		JobDetail jobDetail = JobBuilder.newJob(HiJob.class)
								.usingJobData("count",0)
								.build();
		
		Trigger trigger = TriggerBuilder.newTrigger()
								.startNow()
								.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5))
								.build();
		
		scheduler.scheduleJob(jobDetail,trigger);
		scheduler.start();
				
	}
	
}

不加 @PersistJobDataAfterExecution 注解时是无状态Job,运行效果:

当前时间:2020-10-09 11:03:53
1
当前时间:2020-10-09 11:03:58
1
当前时间:2020-10-09 11:04:03
1
当前时间:2020-10-09 11:04:08
1
当前时间:2020-10-09 11:04:13
1
当前时间:2020-10-09 11:04:18
1

加上 @PersistJobDataAfterExecution 注解后是有状态Job,运行效果:

当前时间:2020-10-09 11:06:25
1
当前时间:2020-10-09 11:06:30
2
当前时间:2020-10-09 11:06:35
3
当前时间:2020-10-09 11:06:40
4
当前时间:2020-10-09 11:06:45
5
当前时间:2020-10-09 11:06:50
6

其他注解:

@DisallowConcurrentExecution

默认的情况下,无论上一次任务是否结束或者完成,只要规定的时间到了,那么下一次就开始。

使用 @DisallowConcurrentExecution 注解可以保证上一次任务成功结束后,下一次任务才能开始

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值