1 Quartz介绍:
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.
介绍来源于Quartz官网,简单说Quartz是开源的特性丰富的任务调度库,可用于多种场景:
- Quartz可以运行嵌入在另一个独立式应用程序。
- Quartz可以在应用程序服务器(或servlet容器)内被实例化,并且参与事务。
- Quartz可以作为一个独立的程序运行(其自己的Java虚拟机内),可以通过RMI使用。
- Quartz可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行。
2 Quartz中的主要概念
Quartz中的主要概念有Job、JobDetail、Trigger、Schedule,其中Job与JobDetail共同定义了需要执行的任务及任务细节,Trigger为触发器,Schedule为调度器。
现在考虑有如下需求:系统运行过程中会产生大量的业务数据,需求为每周一、三、五、七的晚上23:00定时对数据表做增量扫描,对业务数据进行稽核审查。
Job:你想要实现的任务类,每一个Job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。在本例中,通过Job定义业务过程,及增量扫描、稽核审查等;
JobDetail:Job类定义了具体的任务行为,但是Job类中不能定义状态变量,因为job类的execu()在每次执行前都会生成新的实例,执行完毕后实例就会被作为垃圾回收。因此状态变量则需要借助JobDetail进行定义。
Trigger:执行任务的触发器,Trigger定义了任务的具体执行时机或者任务执行规则,如本例中的每周一、三、五、七的晚上23:00定时执行即通过Trigger进行设置。
Schedule:任务的调度器,Schedule将Trigger与JobDetail进行整合,实现对任务的调度,如本例中需要通过Schedule控制定时任务从何时生效、何时暂停、何时终止等。
需要说明的是,Quartz中对Job与Trigger进行了解耦设计,这样的设计可以使任务调度更加灵活。W3cSchool中关于该设计的解释如下:
为什么既有Job,又有Trigger呢?很多任务调度器并不区分Job和Trigger。有些调度器只是简单地通过一个执行时间和一些job标识符来定义一个Job;其它的一些调度器将Quartz的Job和Trigger对象合二为一。在开发Quartz的时候,我们认为将调度和要调度的任务分离是合理的。在我们看来,这可以带来很多好处。
例如,Job被创建后,可以保存在Scheduler中,与Trigger是独立的,同一个Job可以有多个Trigger;这种松耦合的另一个好处是,当与Scheduler中的Job关联的trigger都过期时,可以配置Job稍后被重新调度,而不用重新定义Job;还有,可以修改或者替换Trigger,而不用重新定义与之关联的Job。
几者的关系为:
3 Quartz简单案例
此处只记录在已有项目中使用Quartz实现任务调度的相关内容。
首先需要引入Quartz的maven依赖,maven依赖可以在官网或者Maven仓库中进行搜索。
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
在实际使用过程中,除了前文所述的主要概念涉及的接口类外,还有两个常用的工具类:
- JobBuilder:用于定义/构建JobDetail实例,用于定义作业的实例。
- TriggerBuilder:用于定义/构建触发器实例。
简单案例如下:
Job类定义:
//实现Job接口
public class SayHello implements Job {
//定义待执行的任务
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("Hello Quartz !" + new Date());
}
}
测试类:
public class HelloQuartzDemo {
public static void main(String[] args) throws SchedulerException {
//定义任务实例,将Job类传入Jobdetail
JobDetail jobDetail = JobBuilder.newJob(SayHello.class)
//name:任务的名称(唯一实例);group:任务组的名称
.withIdentity("job", "jobGroup")
.build();
//定义触发器
Trigger trigger = TriggerBuilder.newTrigger()
//name:触发器名称;group:触发器所在组
.withIdentity("trigger", "triGroup")
//定义触发规则
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
//5秒执行一次
.withIntervalInSeconds(5)
//无限循环
.repeatForever())
//立刻启动
.startNow()
.build();
//定义调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//通过schedular组合JobDetail与trigger
scheduler.scheduleJob(jobDetail, trigger);
//调度器启动
scheduler.start();
}
}
启动后,可以观察到控制台每5秒一次输出: