Quartz中的常用组件之间的关系
Posted Tang.Mr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Quartz中的常用组件之间的关系相关的知识,希望对你有一定的参考价值。
注意:
本文应用了Quartz入门中的入门案例作为基础
### 1.Job和JobDetail的关系介绍
- Job:工作任务调度接口,任务类需要实现的接口。该接口中定义了execute方法,类似JDK提供的TimeTask类的run方法。在这里面编写任务执行的业务逻辑
- Job实例在Quartz中的生命周期:每次调度器执行Job时,它在调用execute方法前会创建一个新的Job实例,当调度完成后,管理的Job对象实例将会被释放,释放的实例会被垃圾回收机制回收
@Slf4j
public class HelloJob implements Job {
public HelloJob(){
log.info("实例被创建了");
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " | 任务被执行了");
}
}
- JobDetail:JobDetail为Job实例提供了许多设置属性,已经JobDetaMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助于JobDetail对象来添加Job实例【JobDetail中重要的属性:name[任务实例的唯一标识名称]、group[任务调度实例的组名]、jobClass[任务类信息]、jobDataMap】
@Slf4j
public class HelloSchedulerDemo {
public static void main(String[] args) throws SchedulerException {
//从调度工厂中获取调度器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//通过JobBuilder构建一个任务实例
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
//设置任务的唯一实例名称和任务组名称组名
.withIdentity("job1", "group1")
//构建实例
.build();
//jobDataMap
JobDataMap jobDataMap = jobDetail.getJobDataMap();
//任务实例的唯一标识名称
String name = jobDetail.getKey().getName();
//任务调度实例的组名
String group = jobDetail.getKey().getGroup();
//任务类信息
String clazzName = jobDetail.getKey().getClass().getName();
log.info("jobDataMap:{}", jobDataMap);
log.info("任务实例的唯一标识名称:"+name);
log.info("任务调度实例的组名:"+group);
log.info("任务类信息:"+clazzName);
//通过TriggerBuilder构建触发器实例
SimpleTrigger trigger = TriggerBuilder.newTrigger()
//设置触发器唯一实例名称和触发器的组名
.withIdentity("trigger1", "group1")
//执行计划,每五秒执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
//立即执行
.startNow()
//构建实例
.build();
//调度器绑定任务实例和触发器
scheduler.scheduleJob(jobDetail,trigger);
//开启定时任务
scheduler.start();
}
}
2.JobExecutionContext的介绍
-
当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法
-
Job能通过JobExecuteContext对象访问到Quartz
运行时的环境
以及Job本身的明细数据
- 获取JobDetail相关信息、获取Trigger相关信息、获取Job类本身的信息
/** * @Author ScholarTang * @Date 2021/7/13 10:45 * @Desc 任务类 */ @Slf4j public class HelloJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //通过JobExecutionContext获取JobDetail JobDetail jobDetail = jobExecutionContext.getJobDetail(); JobKey jobKey = jobDetail.getKey(); String jobDetailName = jobKey.getName(); String jobDetailGroup = jobKey.getGroup(); String jobClazzNameJobDetail = jobKey.getClass().getName(); log.info("任务实例的唯一标识名称:" + jobDetailName); log.info("任务实例的组名:" + jobDetailGroup); log.info("任务实例绑定的任务类信息:" + jobClazzNameJobDetail); log.info("-----------------------------------------"); //通过JobExecutionContext获取Trigger Trigger trigger = jobExecutionContext.getTrigger(); TriggerKey triggerKey = trigger.getKey(); String triggerKeyName = triggerKey.getName(); String triggerKeyGroup = triggerKey.getGroup(); String triggerClazzName = triggerKey.getClass().getName(); log.info("触发器的唯一标识名称:" + triggerKeyName); log.info("触发器的组名:" + triggerKeyGroup); log.info("触发器绑定的任务类信息:" + triggerClazzName); log.info("-----------------------------------------"); //通过JobExecutionContext String jobClazzName = jobExecutionContext.getClass().getName(); log.info("job类相关的信息:"+jobClazzName); log.info("-----------------------------------------"); log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " | 任务被执行了"); } }
3.JobDataMap介绍
3.1.使用Map获取
- 在进行任务调度时,JobDataMap存储在JobExecutionContent中,非常方便获取
- JobDataMap可以用来存储任何可序列化的数据对象,当Job实例对象被执行时这些参数都会传递给它
- JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法来存储基本数据类型
/**
* @Author ScholarTang
* @Date 2021/7/13 10:53
* @Desc 调度器
*/
@Slf4j
public class HelloSchedulerDemo {
public static void main(String[] args) throws SchedulerException {
//从调度工厂中获取调度器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//通过JobBuilder构建一个任务实例
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
//设置任务的唯一实例名称和任务组名称组名
.withIdentity("job1", "group1")
//设置jobDataMap数据 <<===============
.usingJobData("message","勇敢牛牛、不怕困难")
//构建实例
.build();
//通过TriggerBuilder构建触发器实例
SimpleTrigger trigger = TriggerBuilder.newTrigger()
//设置触发器唯一实例名称和触发器的组名
.withIdentity("trigger1", "group1")
//设置jobDataMap数据 <<===============
.usingJobData("username","张三")
//执行计划,每五秒执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
//立即执行
.startNow()
//构建实例
.build();
//调度器绑定任务实例和触发器
scheduler.scheduleJob(jobDetail,trigger);
//开启定时任务
scheduler.start();
}
}
/**
* @Author ScholarTang
* @Date 2021/7/13 10:45
* @Desc 任务类
*/
@Slf4j
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//通过JobExecutionContext获取JobDetail
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobKey jobKey = jobDetail.getKey();
String jobDetailName = jobKey.getName();
String jobDetailGroup = jobKey.getGroup();
String jobClazzNameJobDetail = jobKey.getClass().getName();
log.info("任务实例的唯一标识名称:" + jobDetailName);
log.info("任务实例的组名:" + jobDetailGroup);
log.info("任务实例绑定的任务类信息:" + jobClazzNameJobDetail);
log.info("-----------------------------------------");
//通过JobExecutionContext获取Trigger
Trigger trigger = jobExecutionContext.getTrigger();
TriggerKey triggerKey = trigger.getKey();
String triggerKeyName = triggerKey.getName();
String triggerKeyGroup = triggerKey.getGroup();
String triggerClazzName = triggerKey.getClass().getName();
log.info("触发器的唯一标识名称:" + triggerKeyName);
log.info("触发器的组名:" + triggerKeyGroup);
log.info("触发器绑定的任务类信息:" + triggerClazzName);
log.info("-----------------------------------------");
//通过JobExecutionContext
String jobClazzName = jobExecutionContext.getClass().getName();
log.info("job类相关的信息:"+jobClazzName);
log.info("-----------------------------------------");
//获取JobDetail中JobDataMap中的message内容 <<===============
JobDataMap jobDataMap = jobDetail.getJobDataMap();
String message = jobDataMap.getString("message");
log.info("从JobDetail-JobDataMap中或到的message内容为:" + message);
//获取Trigger中JobDataMap中的username内容 <<===============
JobDataMap triggerJobDataMap = trigger.getJobDataMap();
String username = triggerJobDataMap.getString("username");
log.info("从Trigger-JobDataMap中获取到的username内容为:" + username);
log.info("-----------------------------------------");
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " | 任务被执行了");
}
}
3.2.Job实现类中添加setter方法对应JobDataMap的键值,Quartz框架默认的JobFactory实现类在初始化Job实例对象时会自动的调用这些setter方法
调度器的内容是不变的。
注意:如果任务实例和触发器的JobDataMap中使用的是同一个key那么触发器的JobDataMap值会覆盖掉任务实例的值
/**
* @Author ScholarTang
* @Date 2021/7/13 10:45
* @Desc 任务类
*/
@Slf4j
public class HelloJob implements Job {
private String message;
private String username;
public void setMessage(String message) {
this.message = message;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//通过JobExecutionContext获取JobDetail
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobKey jobKey = jobDetail.getKey();
String jobDetailName = jobKey.getName();
String jobDetailGroup = jobKey.getGroup();
String jobClazzNameJobDetail = jobKey.getClass().getName();
log.info("任务实例的唯一标识名称:" + jobDetailName);
log.info("任务实例的组名:" + jobDetailGroup);
log.info("任务实例绑定的任务类信息:" + jobClazzNameJobDetail);
log.info("-----------------------------------------");
//通过JobExecutionContext获取Trigger
Trigger trigger = jobExecutionContext.getTrigger();
TriggerKey triggerKey = trigger.getKey();
String triggerKeyName = triggerKey.getName();
String triggerKeyGroup = triggerKey.getGroup();
String triggerClazzName = triggerKey.getClass().getName();
log.info("触发器的唯一标识名称:" + triggerKeyName);
log.info("触发器的组名:" + triggerKeyGroup);
log.info("触发器绑定的任务类信息:" + triggerClazzName);
log.info("-----------------------------------------");
//通过JobExecutionContext
String jobClazzName = jobExecutionContext.getClass().getName();
log.info("job类相关的信息:"+jobClazzName);
log.info("-----------------------------------------");
//获取JobDetail中JobDataMap中的message内容
//JobDataMap jobDataMap = jobDetail.getJobDataMap();
//String message = jobDataMap.getString("message");
log.info("从JobDetail-JobDataMap中或到的message内容为:" + message);
//获取Trigger中JobDataMap中的username内容
//JobDataMap triggerJobDataMap = trigger.getJobDataMap();
//String username = triggerJobDataMap.getString("username");
log.info("从Trigger-JobDataMap中获取到的username内容为:" + username);
log.info("-----------------------------------------");
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " | 任务被执行了");
}
}
3.3.获取其他
//获取任务的本次执行时间
Date fireTime = jobExecutionContext.getFireTime();
//获取任务的下次执行时间
Date nextFireTime = jobExecutionContext.getNextFireTime();
log.info("任务的本次执行时间:" + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(fireTime));
log.info("任务的下次执行时间:" + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(nextFireTime));
4.有状态的Job和无状态的Job
什么是有状态的Job?什么是无状态的Job?
有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,而默认的无状态Job每次调用时都会创建一个新的JobDataMap
4.1.Job默认是无状态的,通过如下示例查看:
package com.scholartang.quartz.main;
import com.scholartang.quartz.job.HelloJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CoreTrigger;
/**
* @Author ScholarTang
* @Date 2021/7/13 10:53
* @Desc 调度器
*/
@Slf4j
public class HelloSchedulerDemo {
public static void main(String[] args) throws SchedulerException {
//从调度工厂中获取调度器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//通过JobBuilder构建一个任务实例
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
//设置任务的唯一实例名称和任务组名称组名
.withIdentity("job1", "group1")
//设置jobDataMap数据 <<===============
.usingJobData("count",0)
//构建实例
.build();
//通过TriggerBuilder构建触发器实例
SimpleTrigger trigger = TriggerBuilder.newTrigger()
//设置触发器唯一实例名称和触发器的组名
.withIdentity("trigger1", "group1")
//执行计划,每五秒执行一次
.以上是关于Quartz中的常用组件之间的关系的主要内容,如果未能解决你的问题,请参考以下文章