前言
在很多公司,特别是互联网公司,需要在指定的时间进行一些跑批任务来完成业务实现,Java中实现定时的方式有很多,其中可自己实现,也有比较成熟的框架,如: Quartz,今天来介绍一下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是一个功能丰富的开源作业框架,可以集成到几乎任何的Java应用程序中,从最小的独立应用程序或最大的电商系统,Quartz可用于创建数十,数百甚至数十万个简单的作业或复杂的计划,任务定义为标准的Java组件业务,可以执行几乎任何可以对其进行编程的任务,Quartz Scheduler包含许多企业级功能,例如: 支持JTA事务和集群。
功能
- 支持集群,故障转移
- 精确可控的任务调度
- 事务支持等
更多功能请参考: http://www.quartz-scheduler.org/overview/features.html
环境准备
该项目使用intellij IDE+Maven作为开发开发工具。
quartz maven依赖:1
2
3
4
5
6
7
8
9
10
11
12<!-- quartz start-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
<!--quartz end-->
quartz中使用slf4j作为日志工具。
log maven依赖为:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<!--log start-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!--log end-->
简单job实现
有了环境准备,接下来,我们就可以来用一用quartz了,首先,我们写一个job类,实现job接口,实现job接口中的execute方法,在真实环境中,在该方法中一般进行一些业务逻辑的处理,(在本例中,直接打印日志,方便查看有执行)。
Myjob类代码:1
2
3
4
5
6
7
8
9
10
11
12
13/**
* @createTime: 2017年06月20日
* @author: juyuqian
* @version: 0.0.1
* 描述: job任务
*/
public class MyJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("执行execute...........");
}
}
有了任务,就需要有调用job的地方,在本例中,通过main函数的方式来演示任何调用job任务:
代码如下所示: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/**
* @createTime: 2017年06月20日
* @author: juyuqian
* @version: 0.0.1
* 描述:
*/
public class MainQuartzSimple {
/**
* 执行job数据
* @param args
*/
public static void main(String[] args){
try{
//1.获取scheduler 实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2.设置job信息,以及触发器信息
JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("andyqian001","group1").build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").startNow().withSchedule(simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build();
scheduler.scheduleJob(jobDetail, trigger);
//3.开始任务调度
scheduler.start();
//4. 关闭scheduler.shutdown();
}catch(SchedulerException ex){
ex.printStackTrace();
}
}
}
- 首先通过StdSchedulerFactory工厂获取一个默认的Scheduler实例
- 设置JobDetail,注意JobDetail是接口,通过JobBuilder建造者获取一个JobDetail对象. 这里Trigger是一个接口,在Quartz中默认有若干实现类,
其中Trigger的实现类有: - CalendarIntervalTrigger()
- MutableTrigger
- SimpleTrigger
- CoreTrigger
- CronTrigger (通过cron表达式触发)
- DaliyTimeIntervalTrigger
如下图所示:
其类图如下所示: 开启任务调度
效果如下:CronTrigger使用
在这里Job沿用MyJob中的实现方法,
CronTrigger代码如下:/** * @createTime: 2017年06月20日 * @author: juyuqian * @version: 0.0.1 * 描述: */ public class QuartzDataSimple02 { /** * test job的数据信息 */ public static void main(String[] args){ try{ //1. 获取任务调度 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //2. 设置jobDetail以及cronTrigger触发器 JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("andyqian002","group1").build(); CronTriggerImpl cronTrigger = new CronTriggerImpl(); cronTrigger.setName("group1"); cronTrigger.setCronExpression("0/2 * * * * ?"); scheduler.scheduleJob(jobDetail, cronTrigger); //3.开启 scheduler.start(); }catch(SchedulerException ex){ ex.printStackTrace(); }catch(ParseException ex){ ex.printStackTrace(); } } }
这一段代码中涉及到了Cron表达式,现在没明白没关系,跑起来,效果和 简单job实现 的实现是一样的,到这里,我们已经能够简单的使用Quartz了,休息一下,我们一起来看看[0/2 ?]表达式是如何构成的。
Cron表达式
Cron表达式由6个必选字段与1个可选字段组成,以空格为分隔符,其分别为:
字段 | 含义 | 是否必须 | 可选值 | 允许的特殊字符 |
---|---|---|---|---|
seconds | 秒 | 必选 | 0-59 | , - * / |
minutes | 分 | 必选 | 0-59 | , - * / |
hours | 时 | 必选 | 0-23 | , - * / |
daysOfMonth | 天 | 必选 | 1-31 | , - * ? / L W |
months | 月 | 必选 | 0-11 or JAN-DEC | , - * / |
daysOfWeek | 周中的某天 | 必选 | 1-7 or SUN-SAT | , - * ? / L # |
years | 年 | 可选 | 1970-2199 | , - * / |
其中years字段为可选字段,其余均为必选字段。
下表中为特殊字符的含义:
符号 | 解释 | 表达式 | 解释 |
---|---|---|---|
* | 所有值 | 10 ? | 如果*在minutes字段上为每分钟执行 |
? | 表示某一值 | 表示每月的某一天,每周的某一天 | |
- | 指定范围 | 0 0 10-12 ? | 表示10,11,12点均执行 |
, | 与的关系 | 0 0 10,11,12 ? | 表示10,11,12点均执行,与0 0 10-12 ?等价 |
/ | 指定增量 | 0/10 ? | 表示每10秒执行一次,执行秒为:[ 0,10,20,30] |
L | 最后一天 | 0 10 0 L * ? | 每月的最后一天凌晨12点10执行一次 |
# | 第几个星期几 | 0 0 0 ? * 3 # 3 | 每月的第3个星期2执行凌晨12点整执行一次 |
W | 最近的一个工作日 | 0 0 0 15W * ? | 在15号最近的一个工作日执行 |
注意事项:
0 0 0 15W * ? 表示15号最近的一个工作日执行,如果15号是星期日,则为下周一执行,如果15号为星期六,执行时间为周五
小结
以上是Quartz Scheduler框架的使用,其中包括Cron表达是的介绍,你懂了吗?(PS:应该问自己懂了吗?记录这篇文章就是自己容易忘记Cron表达式的书写,自己记录一篇,快忘记了就过来瞅瞅,这就是我写博客的初衷!)