Quartz三个核心概念
- 调度器:Scheduler
- 任务:Job
- 触发器:Trigger
Quartz体系结构
- JobDetail:包含任务的实现类以及类的信息;
- Trigger:决定任务什么时候被调用;分为SimpleTrigger和CronTrigger(常用);
- scheduler:定时、周期地执行JobDetail的信息
Quartz重要组成
- Job: 接口,只有一个参数;
- JobDetail:Job的实现类;
- JobBuilder:创建JobDetail的实例;
- JobStore:保存Job数据;(保存到内存中、数据库中);
- Trigger:
- TreadPool:
- TriggerBuilder:
- Scheduler:调度器;
- Calender:一个Trigger可以和多个Calender关联,以排除或者包含某些时间点
- 监听器:JobListener、TriggerListener、SchedulerListener;
代码示例(一)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package com.weyoung.platform.quartz.schedule;
import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat; import java.util.Date;
public class QuartzJobInit implements Job {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzJobInit.class);
@Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format = sf.format(date); run(format); }
public void run(String format) { LOGGER.info("QuartzJobInit.execute.run:{}", format); System.out.println("QuartzJobInit.execute.run:{}" + format); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.weyoung.platform.quartz.schedule;
import org.quartz.*; import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat; import java.util.Date;
public class TestJob { public static void main(String[] args) { JobDetail jobDetail = JobBuilder.newJob(QuartzJobInit.class).withIdentity("myJob", "group1").build(); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "triggerGroup1") .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build(); StdSchedulerFactory factory = new StdSchedulerFactory(); Scheduler scheduler = null; try { scheduler = factory.getScheduler(); scheduler.start(); Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format = sf.format(date); System.out.println("QuartzJobInit.main" + format);
scheduler.scheduleJob(jobDetail, trigger); } catch (SchedulerException e) { e.printStackTrace(); } } }
|
Job 接口的实现
- Job接口中只有一个execute方法,然后在其中写业务逻辑;
- 生命周期:每次调度器Scheduler在执行job时,会在调用execute方法之前创建一个新的job实例;调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收。
- JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。重要属性如下:
- name
- group 任务所在组
- jobClass 任务实现类
- jobDataMap
JobExecutionContext
- 当Scheduler调用一个Job时,就会将JobExecutionContext传递给Job的execute方法;
- Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。
JobDataMap
- 在进行任务调度时JobDataMap存储在JobExecutionContext中,非常方便获取;
- JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它;
- JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型。
JobDataMap获取方式:
从Map中直接获取;
添加数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| JobDetail jobDetail = JobBuilder.newJob(QuartzJobInit.class) .withIdentity("myJob", "group1") .usingJobData("message", "hello myJob") .usingJobData("FloatJobValue", 3.14F) .build();
Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger", "triggerGroup1") .usingJobData("message", "hello myTrigger") .usingJobData("DoubleTriggerValue", 2.0D) .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
|
获取数据:
1 2 3 4 5 6 7 8 9 10 11
| JobKey key = context.getJobDetail().getKey(); System.out.println("key============>" + key.getName()+":" + key.getGroup()); TriggerKey triggerKey = context.getTrigger().getKey(); System.out.println("triggerKey============>" + triggerKey.getName()+":" + triggerKey.getGroup()); JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); JobDataMap dataMap = context.getTrigger().getJobDataMap();
String message = jobDataMap.getString("message"); float floatJobValue = jobDataMap.getFloatValue("FloatJobValue"); String triggerMsg = dataMap.getString("message"); double doubleJobValue = dataMap.getDoubleValue("DoubleTriggerValue");
|
- 方式二:getMergedJobDataMap
- Trigger和JobDetail中有相同的key时,Trigger中的值就会覆盖掉JobDetail中的值。
- Job实现类中添加setter方法对应JobDataMap的键值(Quartz框架默认的JobFactory实现类在初始化job实例对象时会自动调用这些setter方法)。
- 直接定义属性,添加getter和setter方法即可;
1
| JobDataMap mergedJobDataMap = context.getMergedJobDataMap();
|
触发器 Trigger
重要的两个实现类
- CronTriggerImpl
- 基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用;
- CRON表达式:L可以和W一起使用;周字段的英文字母不区分大小写;
- SimpleTriggerImpl
- 在一个指定时间段内执行一次作业任务;或者在指定时间间隔内多次执行作业任务;
- 重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值。
- 重复时间间隔必须是0或者长整数;
- 一旦制定了endAt,那么它就会覆盖重复次数参数的效果。endAt优先于withRepeatCount;
重要属性
- JobKey:job实例的标识,触发器被触发时,该jobkey指定的实例会被触发执行;
- StartTime:触发器首次被触发的时间;类型java.util.Date;
- EndTime:触发器不再被触发的时间;类型java.util.Date;
调度器Scheduler
Scheduler-工厂模式
- SchedulerFactory创建的;
- StdSchedulerFactory;
- 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器;
- 配置参数一般在quartz.properties中
- 调用getScheduler方法就能创建和初始化调度器对象;
- DirectSchedulerFactory;
主要函数
- Date scheduleJob(JobDetail jobDetail, Trigger trigger);绑定jobDetail和trigger注册进scheduler中;返回最近一次即将执行的时间;
- void start(); // 启动
- void standby();// 挂起,挂起后可通过start恢复
- void shutdown();// 关闭,不能恢复执行,强行恢复报出异常
- shutdown(true):// 等待所有正在执行的job执行完毕之后,再关闭scheduler;
- shutdown(false):// 表示直接关闭scheduler
quartz.properties
- 文档的位置及加载顺序;优先读取工程中自定义的,没有的话去读quartz中的文件;
- 组成部分
- 调度器属性
- org.quartz.scheduler.instanceName:用来区分特定的调度器实例,可以按照功能用途来给调度器起名;
- org.quartz.scheduler.instanceId:和前者一样,也允许任何字符串,但这个值必须在所有调度器实例中是唯一的,尤其是在一个集群当中,作为集群的唯一key。如果想让Quartz生成这个值的话,可以设置为AUTO;
- 线程池属性
- threadCount:指定线程数,至少为1;
- threadPriority:线程的优先级;
- org.quartz.threadPool.class:线程池的实现类;
- 作业存储设置
- 描述了在调度器实例的生命周期中,Job和Trigger的信息是如何被存储的;
- 插件配置
详细配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
org.quartz.scheduler.instanceName: DefaultQuartzScheduler org.quartz.scheduler.instanceid:AUTO org.quartz.scheduler.rmi.export: false org.quartz.scheduler.rmi.proxy: false org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy} org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = my_quartz_job2.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.jobInitializer.scanInterval = 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
|
基于Maven的SpringMvc工程整合Quartz
使用Quartz配置作业
- MethodInvokingJobDetailFactoryBean;
- JobDetailFactoryBean:比较灵活,支持给作业传递数据;
Quartz相关文档
相关链接
本文整理自:慕课网教程
Java定时任务调度工具详解之Quartz篇:https://www.imooc.com/learn/846