概述
- Quartz:是一个开放源代码任务调度框架。Quartz功能强大,可以让你的程序在指定时间执行,也可以按照某一个频度执行,支持数据库、监听器、插件、集群等特性。
- 使用场景:定时消息推送、定时抢购、定时发送邮件、定时统计等。
体系架构
- Job
是一个接口,只定义一个方法execute(JobEexcutionContext context),在实现接口的execute方法中编写所需要定时执行的Job任务,JobEexcutionContext 类提供了调度应用的一些信息。Job运行时的信息保存在JobDataMap实例中。 - JobDetail
JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。sheduler每次执行,都会根据JobDetail创建一个新的Job实例 - Trigger
是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当且仅当需要调度一次或者以固定时间间隔周期执行调度,SimpleTrigger是最适合简单任务的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如工作日周一到周五的15:00~16:00执行调度等。
Cron表达式
- 表达式的格式:秒 分 时 日 月 周 年(可选)。
字段名 | 允许的值 | 允许的特殊字符 |
---|---|---|
秒 | 0-59 | , – * / |
分 | 0-59 | , – * / |
时 | 0-23 | , – * / |
日 | 1-31 | , – * / L W C |
月 | 1-12 or JAN-DEC | , – * / |
周 | 1-7 or SUN-SAT | , – * ? / L C # MON FRI |
年(可选字段) | empty, 1970-2099 | , – * / |
允许的特殊字符:
- * 字符代表:代表所有可能的值。因此,“*”在Month中表示每个月,在Day-of-Month中表示每天,在Hours表示每小时
- “,”字符:指定数个值。例如:在Minutes子表达式中,“5,20”表示在5分钟和20分钟触发。
- “-”字符:指定一个值的范围
- “/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m。例如:在Minutes子表达式中,“0/15”表示从0分钟开始,每15分钟执行一次。“3/20"表示从第三分钟开始,每20分钟执行一次。和"3,23,43”(表示第3,23,43分钟触发)的含义一样。
- “L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X
- “W”字符:指定离给定日期最近的工作日(周一到周五)
- “#”字符:表示该月第几个周X。6#3表示该月第3个周五
- ? 字符:用在Day-of-Month和Day-of-Week中,指“没有具体的值”。当两个子表达式其中一个被指定了值以后,为了避免冲突,需要将另外一个的值设为“?”。例如:想在每月20日触发调度,不管20号是星期几,只能用如下写法:0 0 0 20 * ?,其中最后以为只能用“?”,而不能用“*”。
- C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。
Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。
Cron表达式范例例:
1. 每隔5秒执行一次:*/5 * * * * ?
2. 每隔1分钟执行一次:0 */1 * * * ?
3. 每天23点执行一次:0 0 23 * * ?
4. 每天凌晨1点执行一次:0 0 1 * * ?
5. 每月1号凌晨1点执行一次:0 0 1 1 * ?
6. 每月最后一天23点执行一次:0 0 23 L * ?
7. 每周星期天凌晨1点执行一次:0 0 1 ? * L
8. 在26分、29分、33分执行一次:0 26,29,33 * * * ?
9. 每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
- Scheduler 代表一个Quartz的独立运行容器, Trigger和JobDetail可以注册到Scheduler中, 两者在 Scheduler中拥有各自的组及名称, 组及名称是Scheduler查找定位容器中某一对象的依据, Trigger的组及名称必须唯一, JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相 同,因为它们是不同类型的)。Scheduler定义了了多个接口方法, 允许外部通过组及名称访问和 控制容器中Trigger和JobDetail。
- JobBulider 用于定义/构建已经定义了了Job实例的JobDetail实例。
- TriggerBuilder 用于定义/构建Trigger实例例。
代码示例
- 添加依赖
<!-- Quartz坐标 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加Scheduled坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Sprng tx 坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
- 定时任务框架/自定义任务类、实现Job
public class MyQuartz implements Job {
@Override
public void execute(JobExecutionContext jobExeutionContext) throws JobExecutionException {
LocalDateTime time = LocalDateTime.now();
System.out.println("执行任务。。。。。。" + time);
}
}
- 编写Quartz的启动类。关联自定义任务类、编写执行规则
@Configuration
public class QuartzConfig {
/**
* 创建 Job 对象
*
* @return 任务细节工厂
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean factory = new JobDetailFactoryBean();
// 关联自定义的 Job 类
factory.setJobClass(MyQuartz.class);
return factory;
}
/**
* 创建Scheduler对象
* 这里我们根据自己的需求可以选择使用 SimpleTriggerFactoryBean对象或者 CronTriggerFactoryBean对象作为参数
* @return 程序调度工厂
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean) {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
// 关联 Trigger
schedulerFactoryBean.setTriggers(cronTriggerFactoryBean.getObject());
return schedulerFactoryBean;
}
/**
* 创建 Trigger 对象
* 和cronTriggerFactoryBean()方法类似、基于简单的时间调度规则
* @param jobDetailFactoryBean
* @return 基于调度间隔时间
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
// 关联JobDetail对象
factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
// 定义执行规则 (该参数表示一个执行的毫秒数)
factoryBean.setRepeatInterval(2000);
// 重复次数 默认无限重复
factoryBean.setRepeatCount(-1);
return factoryBean;
}
/**
* 创建 Trigger 对象
* 和simpleTriggerFactoryBean()方法类似、基于Cron表达式、可以满足复杂的时间调度规则
* @param jobDetailFactoryBean
* @return 基于时间刻度(可以设置具体时间)
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
CronTriggerFactoryBean cron = new CronTriggerFactoryBean();
// 关联JobDetail对象
cron.setJobDetail(jobDetailFactoryBean.getObject());
// 指定Cron表达式
cron.setCronExpression("*/1 * * * * ?");
return cron;
}
}
- 修改启动类:加上@EnableScheduling注解
@SpringBootApplication
@EnableScheduling
public class ApplicationRun {
public static void main(String[] args) {
SpringApplication.run(ApplicationRun.class, args);
}
}