Quartz(一)

时间:2023-12-24 20:55:07

1 Quartz介绍

  • 定时任务,无论是互联网公司还是传统的软件行业都是必不可少的,Quartz是好多优秀的定时任务开源框架的基础的。
  • 我们应用最简单和最基础的配置,不需要太多参数,就可以轻松掌握企业中的定时任务处理。

2 Quartz概念

  • Quartz是OpenSymphony开源组织在Job Scheduling领域又一个开源项目,它可以在J2EE和J2SE应用程序相结合,也可以单独使用。
  • Quartz是开源且具有丰富特性的“任务调度库”,能够集成于任何的Java应用,小到独立的应用,大到电子商业系统。
  • Quartz能够创建亦简单亦复杂的调度,以执行上十、上百,甚至上万的任务。
  • 任务Job被定义为标准的Java组件,能够执行任何你想要的功能。
  • Quartz调度框架包含许多企业级的特性,如JTA事务、集群的支持。
  • 简而言之,Quartz就是基于Java实现的任务调度框架,用于执行你想要执行的任何任务。

3 Quartz的运行环境

  • Quartz可以运行嵌入在另一个独立式应用程序。
  • Quartz可以在应用程序服务器(或者Servlet容器)内被实例化,并且参与事务。
  • Quartz可以作为一个独立的程序运行(其自己的Java虚拟机内),可以通过RMI使用。
  • Quartz可以被实例化,作为独立的项目集群(负载均衡和故障转移的功能),用于作业的执行。

4 Quartz的核心概念

4.1 任务 Job

  • Job就是你想要实现的任务类,每一个Job必须实现org.quartz.Job接口,且只需要实现接口定义的execute()方法。

4.2 JobDetail

  • 表示一个具体的可执行的调度程序,Job是这个可执行调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。

4.3 触发器 Trigger

  • Trigger就是执行任务的触发器,比如每天定时3点发送一份统计邮件,Trigger将会设置3点进行该任务。
  • Trigger主要包含SimpleTrigger和CronTrigger两种。

4.4 调度器 Scheduler

  • Scheduler为任务的调度器,它会将任务Job和触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job。

5 Quartz的体系结构

Quartz(一)

6 Quartz常用的API

6.1 Scheduler

  • Scheduler--和调度程序交互的主要API。

6.2 Job

  • Job就是你想要实现的任务类,每一个Job必须实现org.quartz.Job接口,且只需要实现接口定义的execute()方法。

6.3 JobDetail

  • 表示一个具体的可执行的调度程序,Job是这个可执行调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。

6.4 Trigger

  • 触发器,定义执行给定作业的计划的组件。

6.5 JobBuilder

  • 用于定义/构建JobDetail实例。

6.6 TriggerBuilder

  • 用于定义/构建Trigger实例。

7 Quartz的入门

7.1 导入环境所需要的jar包的maven坐标

<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<!-- quartz-jobs -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

7.2 在classpath类路径下新建log4j.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="default" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p] %d{dd MMM hh:mm:ss.SSS aa} %t [%c]%n%m%n%n"/>
</layout>
</appender> <logger name="com.how2java">
<level value="error" />
</logger> <root>
<level value="error" />
<appender-ref ref="default" />
</root> </log4j:configuration>

7.3 入门示例

  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; public class MailJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
Object email = jobDataMap.get("email"); System.out.println("邮件发送给" + email + ",发送时间是:" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
}
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
/**
* ①创建JobDetail实例,通过JobBuilder来创建
*
*/
JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.usingJobData("email", "123456789@qq.com")
.build();
/**
* ②创建Trigger示例,通过TriggerBuilder来创建。
* 在Quartz中,Job只是用来表示 什么任务,而Trigger用来表示 什么时候做,怎么做(设置执行的条件等)?
*/
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
//设置调度的参数 withIntervalInSeconds(2) 表示时间间隔是2秒,repeatForever() 一直重复执行,直到天崩地裂,海枯石烂。
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build(); //通过StdSchedulerFactory工厂的getDefaultScheduler()方法获取Scheduler调取器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); /**
*③ 调度器将jobDetail和trigger关联起来
*/
scheduler.scheduleJob(jobDetail, trigger); /**
* ④ 触发器开启
* 注意:
* scheduler被停止后,除非重新实例化,否则不能重新启动;
* 只有当scheduler启动后,即使处于暂停状态也不行,trigger才会被触发(job才会被执行)
*/
scheduler.start();
} }

8 Job和JobDetail介绍

8.1 Job

  • Job:工作任务调度的接口,任务类需要实现该接口。该接口中定义execute方法,类似于JDK提供的TimeTask类的run方法。在里面编写任务执行的业务逻辑即可。
  • Job实例在Quartz中的生命周期:每次调度器执行Job的时候,它会在调用execute方法前创建一个新的Job实例,当调用完成之后,关联的Job对象实例会被释放,释放的实例会被垃圾回收器回收。

8.2 JobDetail

  • JobDetail:JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定的Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
  • JobDetail重要属性:name、group、jobClass、jobDataMap。

8.3 应用示例

  • 示例:
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
/**
* ①创建JobDetail实例,通过JobBuilder来创建
*
*/
JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.usingJobData("email", "123456789@qq.com")
.build(); System.out.println("名称:" + jobDetail.getKey().getName());
System.out.println("组的名称:" + jobDetail.getKey().getGroup()); //如果没有指定,默认以DEFAULT为组名
System.out.println("任务类:" + jobDetail.getJobClass().getName()); /**
* ②创建Trigger示例,通过TriggerBuilder来创建。
* 在Quartz中,Job只是用来表示 什么任务,而Trigger用来表示 什么时候做,怎么做(设置执行的条件等)?
*/
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
//设置调度的参数 withIntervalInSeconds(2) 表示时间间隔是2秒,repeatForever() 一直重复执行,直到天崩地裂,海枯石烂。
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build(); //通过StdSchedulerFactory工厂的getDefaultScheduler()方法获取Scheduler调取器实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); /**
*③ 调度器将jobDetail和trigger关联起来
*/
scheduler.scheduleJob(jobDetail, trigger); /**
* ④ 触发器开启
* 注意:
* scheduler被停止后,除非重新实例化,否则不能重新启动;
* 只有当scheduler启动后,即使处于暂停状态也不行,trigger才会被触发(job才会被执行)
*/
scheduler.start();
} }

9 JobExecutionContext和JobDataMap介绍

9.1 JobExecutionContext

  • 当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法。
  • Job能够通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。
  • 示例:
package com.sunxiaping;

import org.quartz.*;

import java.util.Date;

public class MailJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
//获取JobDetail
JobDetail jobDetail = context.getJobDetail();
System.out.println("工作任务的名称:" + jobDetail.getKey().getName() + ",工作任务的组:" + jobDetail.getKey().getGroup());
System.out.println("任务类的名称(全类名):"+jobDetail.getJobClass().getName());
System.out.println("任务类的名称:"+jobDetail.getJobClass().getSimpleName());
//获取Trigger
Trigger trigger = context.getTrigger(); System.out.println("触发器的名称:" + trigger.getKey().getName() + ",触发器的组:" + trigger.getKey().getGroup()); Date fireTime = context.getFireTime();
System.out.println("当前任务的执行时间:"+fireTime);
Date nextFireTime = context.getNextFireTime();
System.out.println("下一次任务的执行时间:"+nextFireTime);
}
}

9.2 JobDataMap

9.2.1 使用Map获取

  • 在进行任务调度的时候,JobDataMap存储在JobExecutionContext中,非常方便虎丘。
  • JobDataMap可以用来装载任何可序列化的数据对象,当Job实例对象被执行的时候这些参数对象会传递给它。
  • JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法用来存取基本数据类型。
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.*;

public class MailJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
String message = context.getJobDetail().getJobDataMap().getString("message");
System.out.println("JobDetail-->JobDataMap:"+message); message = context.getTrigger().getJobDataMap().getString("message");
System.out.println("Trigger-->JobDataMap:"+message);
}
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException { JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
//usingJobData 非常方便的存取基本类型数据
.usingJobData("message", "JobDetail")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
//设置调度的参数 withIntervalInSeconds(2) 表示时间间隔是2秒,repeatForever() 一直重复执行,直到天崩地裂,海枯石烂。
.usingJobData("message","trigger")
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start();
} }

Quartz(一)

9.2.2 Job实现类中添加Setter方法对应JobDataMap的键值

  • Quartz框架默认的JobFactory实现类在初始化Job实例对象的时候回自动的调用这些Setter方法。
  • 示例:
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; public class MailJob implements Job { private String message; public void setMessage(String message) {
this.message = message;
} public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println(message);
}
}
  • 注意:这种方式有弊端,那就是如果遇到同名的key,Trigger中的JobDataMap会覆盖掉JobDetail中的JobDataMap中的值。

10 有状态的Job和无状态的Job

  • 其实就是@PersistJobDataAfterExecution注解的使用。
  • 有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中。
  • 默认情况下,无状态的Job每次调用都会创建一个新的JobDataMap。
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution; @PersistJobDataAfterExecution
public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
int count = context.getJobDetail().getJobDataMap().getInt("count");
count++;
System.out.println(count);
context.getJobDetail().getJobDataMap().put("count", count); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException { JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
//usingJobData 非常方便的存取基本类型数据
.usingJobData("count", 0)
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
//设置调度的参数 withIntervalInSeconds(2) 表示时间间隔是2秒,repeatForever() 一直重复执行,直到天崩地裂,海枯石烂。
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start();
} }

11 Trigger介绍

Quartz(一)

  • Quartz有一些不同的触发器类型,不过,用的最多的还是SimpleTrigger和CronTrigger。
  • JobKey:表示Job实例的标识,触发器被触发时,该指定的Job实例会被执行。
  • startTime:表示触发器第一次开始被触发的时间,它的数据类型是java.util.Date。
  • endTime:表示触发器终止被触发的时间,它的数据类型是java.util.Date。
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
//表示Job实例的标识,触发器被触发时,该指定的Job实例会被执行
JobKey jobKey = context.getTrigger().getJobKey();
System.out.println("JobKey的名称:" + jobKey.getName() + ",JobKey组的名称:" + jobKey.getGroup());
//触发器第一次开始被触发的时间
Date startTime = context.getTrigger().getStartTime();
System.out.println("startTime:" + startTime);
//触发器终止被触发的时间
Date endTime = context.getTrigger().getEndTime();
System.out.println("endTime:" + endTime); System.out.println("当前时间是:"+new Date()); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
//usingJobData 非常方便的存取基本类型数据
.usingJobData("count", 0)
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
// .startNow() //立即开始,在Scheduler调度器开启之后
.startAt(startDate)//设置任务的开始时间
.endAt(endDate) //设置任务的结束时间 //设置调度的参数 withIntervalInSeconds(2) 表示时间间隔是2秒,repeatForever() 一直重复执行,直到天崩地裂,海枯石烂。
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }

12 SimpleTrigger触发器

  • SimpleTrigger对于设置和使用时最为简单的一种QuartzTrigger。
  • 它是为那种需要在特定的日期/时间启动,且以一种可能的间隔时间重复执行n次的Job所设计的。
  • 示例:在一个指定的时间段内,执行一次作业任务
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("当前时间是:"+new Date()); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
// .startNow() //立即开始,在Scheduler调度器开启之后
.startAt(startDate)//设置任务的开始时间
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
  • 示例:在指定的时间间隔内多次执行作业任务
  • MailJob.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
// .startNow() //立即开始,在Scheduler调度器开启之后
.startAt(startDate)//设置任务的开始时间
//设置调度的参数 withIntervalInSeconds(2) 表示时间间隔是2秒,withRepeatCount(4) 执行5次 每1秒执行一次,连续执行5次后停止
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(4))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
  • 示例:设置任务的结束时间
  • MailJob.java
package com.sunxiaping;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import java.util.Date; public class MailJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("当前时间是:"+new Date()); }
}
  • QuartzTest.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
// .startNow() //立即开始,在Scheduler调度器开启之后
.startAt(startDate)//设置任务的开始时间
.endAt(endDate)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
  • 注意:
  • SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔。
  • 重复次数的属性值可以为0、正整数、或常量SimpleTrigger.REPEAT_INDEFINITELY。
  • 重复的时间间隔属性值必须大于0或长整型的正整数,以毫秒作为时间单位。
  • 如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒就触发一次知道指定的结束时间的Trigger,而无需去计算从开始到结束所重复的次数,我们只需要简单的指定结束书剑和使用REPEAT_INDEFINITELY。

13 CronTrigger触发器

13.1 概述

  • 如果你需要像日历那样按照日程来触发任务,而不是像SimpleTrigger那样每隔特定的间隔时间触发,CronTrigger通常比SimpleTrigger更有用,因为它是基于日历的作业调度。
  • 使用CronTrigger,你可以指定诸如“每个周五中午”,或者“每个工作日的0:30”或者“从每个周一、周三、周五的上午9点到10点之间每隔五分钟”这样的日程来安排触发。甚至,像SimpleTrigger一样,CronTrigger也有一个startTime以指定日程从什么时候开始,也有一个(可选的)endTime以指定何日日程不再继续。

13.2 Cron表达式

  • Cron表达式被用来配置CronTrigger实例。Cron表达式是一个由7个子表达式组成的字符串。每个子表达式都描述了一个单独的日程细节。这些子表达式之间使用空格分隔,分别表示:
  • ①Seconds,秒。
  • ②Minutes,分钟。
  • ③Hours,小时。
  • ④Day-of-Month,月中的天。
  • ⑤Month,月。
  • ⑥Day-of-Week,周中的天。
  • ⑦year(optional field) 年,可选。

Quartz(一)

  • 单个子表达式可以包含范围或者列表。例如周中的天这个域(‘WED’)可以被替换为''MON-FRI"或"MON,WED,FRI"或者甚至“MON-WED,SAT”。
  • 所有的域中的值都有特定的合法范围,这些值得合法范围相当明显,例如:秒和分钟的合法值是0~59,小时的合法值是0~23,Day-of-Month的合法值是1~31,但是需要注意不同的月份中的天数是不一样的。月份的合法值是1~12(你也可以用字符串JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC来表示)。Days-of-Week可以用1-7来表示(其中1表示星期日)或者用字符串SUN,MON,TUE,WED,THU,FRI,SAT来表示。

Quartz(一)

  • 示例:
  • 0 0 10,14,16 * * ?:每天上午10点,下午2点,4点。
  • 0 0/30 9-17 * * ? :每天早上9点晚上5点工作,从0分钟开始,每隔30分钟发送一次。
  • 0 0 12 ? * WED :每个星期三中午12点。
  • 0 0 12 * * ?:每天中午12点触发。
  • 0 15 10 ? * * :每天上午10点15分触发。
  • 0 12 10 * * ? 2050:2050年上午10点12分触发。
  • 0 * 14 * * ?:每天下午2点到下午2点59分,每隔1分钟触发一次。
  • 0 0/55 14 * * ?:每天下午2点到下午2点55分钟,从0开始到55分钟触发。
  • 0 0/55 14,18 * * ?:每天下午2点到2:55期间和下午6点到6:55期间,从0开始到55分钟触发。
  • 0 0-5 14 * * ?:每天下午2点到下午2:05期间每隔1分钟触发。
  • 0 10,44 14 ? 3 WED:每年三月的星期三下午2点10和2点44触发。
  • 0 15 10 ? * MON-FRI:周一到周五的上午10点15分触发。
  • 0 15 10 15 * ?:每月15号上午10点15分触发。
  • 0 15 10 L* ?:每月最后一日的上午10点15分触发。
  • 0 15 10 ? * 6L:每月最后一个星期五上午10点15分触发。
  • 0 15 10 ?* 6#3:每月的第三个星期五上午10点15分触发。
  • 示例:
  • MailJob.java
package com.sunxiaping;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory; import java.util.Date; /**
* Quartz测试
*/
public class QuartzTest { public static void main(String[] args) throws SchedulerException {
Date startDate = new Date();
startDate.setTime(startDate.getTime() + 3000); Date endDate = new Date();
endDate.setTime(endDate.getTime() + 10000); JobDetail jobDetail = JobBuilder.newJob(MailJob.class)
.withIdentity("job1", "group1")
.build(); Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow() //立即开始,在Scheduler调度器开启之后
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
  • 提示:
  • L和W可以一起使用。(企业中可用在工资计算,比如每个月5号发工资)
  • #可表示月中的第几个周几。(比如父亲节和母亲节)
  • 周字段英文字母大小写不区分。比如MON==mon。
  • 利用工具,在线生成。