Quartz
文章目录
1.什么是Quartz
Quartz是功能强大的开源作业调度库,几乎可以集成到任何Java应用程序中-从最小的独立
应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数以万
计,数以万计的工作。任务定义为标准Java组件的作业,它们实际上可以执行您可以对其执行的任何编程操作。Quartz Scheduler包含许多企业级功能,例如对JTA事务和集群的
支持。
- Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作
业调度提供了简单却强大的机制。 - Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。
- Quartz 允许程序开发人员根据时间的间隔来调度作业
- Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。
3.Quartz核心概念
- Job 表示一个工作,要执行的具体内容。此接口中只有一个方法
void execute(JobExecutionContext context);
- JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执
行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。 - Trigger 代表一个调度参数的配置,什么时候去调
- Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和
Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。 - JobBuilder 用于定义/构建JobDetail实例,用于定义作业的实例。
- TriggerBuilder 用于定义/构建触发器实例。
3.Quartz的运行环境
- Quartz 可以运行嵌入在另一个独立式应用程序。
- Quartz 可以在应用程序服务器(或 servlet 容器)内被实例化,并且参与 XA 事务。
- Quartz 可以作为一个独立的程序运行(其自己的 Java 虚拟机内),可以通过 RMI 使
用。 - Quartz 可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的
执行。
4.定时任务的应用场景
- 时间驱动:信用卡账单、还款通知
- 批量处理:银行核心系统夜间跑批(对账、结账、日切)
- 异步/解耦:半小时打包一次(登记入库->打包发送)
5.起步
5.1 添加项目依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</depende>
5.2 添加一个工作Job
public class MyJob1 implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss");
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
System.out.println(" "+dateFormat.format(date)+"任务1执行
了,"+dataMap.getString("hdax"));
}
}
5.3API测试
public static void main(String[] args) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(MyJob1.class)
.withIdentity("job1","group1")
.usingJobData("hdax","我们承诺使支持你成为受人尊重的专业人才!")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("tigger1","group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
5.4 配置
# 名为:quartz.properties,放置在classpath下,如果没有此配置则按照默认配置启
动
# 指定调度器名称,非实现类
org.quartz.scheduler.instanceName = DefaultQuartzScheduler04
# 指定线程池实现类
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# 线程池数量
org.quartz.threadPool.threadCount = 10
# 优先级,默认5
org.quartz.threadPool.threadPriority = 5
# 非持久化job
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
6. Trigger
6.1 SimpleTrigger
指定从某一时间开始,以一定的时间间隔(单位是毫秒)执行的任务。
它适合的任务类似于: 9:00开始,每隔1小时,执行一次。
它的属性有:
repeatInterval 重复间隔
repeatCount 重复次数。实际执行次数是 repeatCount+1。因为在startTime的时
候一定会执行一次。
6.2 CalendarIntervalTrigger
类似于SimpleTrigger,指定从某一个时间开始,以一定的时间间隔执行的任务。但
是不同的是SimpleTrigger指定的时间间隔为毫秒,没办法指定每隔一个月执行一次
(每月的时间间隔不是固定值),而CalendarIntervalTrigger支持的间隔单位有秒,
分钟,小时,天,月,年,星期。
6.3 DailyTimeIntervalTrigger
指定每天的某个时间段内,以一定的时间间隔执行任务。并且它可以支持指定星期。
它适合的任务类似于:指定每天9:00 至 18:00,每隔70秒执行一次,并且只要周一到
周五执行。
它的属性有:
startTimeOfDay 每天开始时间
endTimeOfDay 每天结束时间
daysOfWeek 需要执行的星期
interval 执行间隔
intervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期)
repeatCount 重复次数
DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule()
.startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9,0)) //每天9:00开始
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(18,0)) //18:00结束
.onDaysOfTheWeek(DailyTimeIntervalScheduleBuilder.MONDAY_THROUGH_FRIDAY)
//周一至周五执行
.withIntervalInHours(1) //每间隔1小时执行一次
.withRepeatCount(100) //最多重复100次(实际执行次数100+1)
6.4 Core Tigger
适合于更复杂的任务,它支持类型于Linux Cron的语法(并且更强大)。基本上它覆
盖了以上三个Trigger的绝大部分功能(但不是全部)。
它适合的任务类似于:每天0:00,9:00,18:00各执行一次。
6.4.2 cron表达式
顺序 | 秒 | 分钟 | 小时 | 日期 | 月份 | 星期 | 年(可选) |
---|---|---|---|---|---|---|---|
取值 | 0-59 | 0-59 | 0-23 | 1-30(31) | 1-12 | 1-7 | |
允许特殊字符 | , - * / | , - * / | , - * / | , - * / ? L W C | , - * / | , - * / L # C | 1970-2099 , - * / |
字段含义
*: 代表所有可能的值
-: 指定范围
,: 列出枚举 例如在分钟里,"5,15"表示5分钟和20分钟触发
/: 指定增量 例如在分钟里,"3/15"表示从3分钟开始,每隔15分钟执行一次
?: 表示没有具体的值,使用?要注意冲突
L: 表示last,例如星期中表示7或SAT,月份中表示最后一天31或30,6L表示这个月的
倒数第6天,FRIL表示这个月的最后一个星期五
W: 只能用在月份中,表示最接近指定天的工作日
#: 只能用在星期中,表示这个月的第几个周几,例如6#3表示这个月的第三个周五
6.4.2 表达式示例
表达式 | 说明 |
---|---|
秒 分 时 日 月 周 | |
0 0 12 * * ? | 每天12点运行 |
0 15 10 * * ? | 每天10:15运行 |
0 15 10 * * ? 2008 | 在2008年的每天10:15运行 |
0 * 14 * * ? | 每天14点到15点之间每分钟运行一次,开始于14:00,结束于14:59 |
0 0/5 14 * * ? | 每天14点到15点每5分钟运行一次,开始于14:00,结束于14:55 |
0 0/5 14,18 * * ? | 每天14点到15点每5分钟运行一次,此外每天18点到19点每5分钟也运行一次 |
0 0-5 14 * * ? | 每天14:00到14:05,每分钟运行一次 |
0 0-5/2 14 * * ? | 每天14:00到14:05,每2分钟运行一次 |
0 10,44 14 ? 3 WED | 3月每周三的14:10和14:44,每分钟运行一次 |
0 15 10 ? * MONFRI | 每周一、二、三、四、五的10:15运行、 |
0 15 10 15 * ? | 每月15日10:15运行 |
0 15 10 L * ? | 每月最后一天10:15运行 |
0 15 10 ? * 6L | 每月最后一个星期五10:15运行【此时天必须是"?"】 |
0 15 10 ? * 6L 2007-2009 | 在2007,2008,2009年每个月的最后一个星期五的10:15运行 |
0 15 10 ? * 6#3 | 每月的第三个星期五的10:15分运行 |
7.Spring整合
7.1 添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
7.2 Spring配置文件
<bean id="jobDetailFactoryBean"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!--指定job的名称-->
<property name="name" value="myJob1"/>
<!--指定job的分组-->
<property name="group" value="myGroup1" />
<!--指定具体的job类-->
<property name="jobClass" value="com.hdax.quartz.job.MyJob1"/>
<!--如果为false,当没有活动的触发器与之关联时会在调度器中会删除该任务(可选)-->
<property name="durability" value="true"/>
<property name="jobDataMap">
<bean class="org.quartz.JobDataMap">
<constructor-arg index="0">
<map>
<entry key="hdax" value="我们承诺,支持你成为受人尊敬的专业人才!"/>
</map>
</constructor-arg>
</bean>
</property>
</bean>
<!--定义触发器的bean,定义一个Cron的Trigger,一个触发器只能和一个任务进行绑
定-->
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!--指定触发器的名称-->
<property name="name" value="myTrigger"/>
<!--指定触发器的组名称-->
<property name="group" value="myGroup2"/>
<!--指定触发器绑定的工作任务-->
<property name="jobDetail" ref="jobDetailFactoryBean"/>
<!--指定Cron表达式-->
<property name="cronExpression" value="*/5 * * * * ?"/>
</bean>
<!--定义调度器,并将Trigger注册到调度器中-->
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
</list>
</property>
<!--添加quartz配置文件-->
<!--<property name="configLocation"
value="classpath:quartz.properties"/>-->
</bean>