目录

官网:Quartz Enterprise Job Scheduler
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与2EE与|2SE应用程序相结合也可以单独使用。
quartz是开源且具有丰富特性的"任务调度库",能够集成于任何的java应用,小到独立的应用,大至电子商业系统。quartz能够创建亦简单亦复杂的调度,以执行上十、上百,甚至上万的任务。任务job被定义为标准的java组件,能够执行任何你想要实现的功能。quartz调度框架包含许多企业级的特性,如JTA事务、集群的支持。
简而言之,quartz就是基于java实现的任务调度框架,用于执行你想要执行的任何任务。
- Quartz 可以运行嵌入在另一个独立式应用程序
- Quartz 可以在应用程序服务器(或servlet容副内被实例化,并且参与事务)
- Quartz 可以作为一个独立的程序运行(其自己的ava虚拟机内),可以通过RMI使用
- Quartz 可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行
- Builder模式
- Factory模式
- 组件模式 JobDetail Trigger
- 链式编程
Job就是你想要实现的任务类,每一个Job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。
Triger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点进行执行该任务。Trigger主要包含两种SimpleTrigger和CronTrigger两种。关于二者的区别的使用场景,后续会进行讨论。
Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Triggeri设定的时间来执行Job.

以下是Quartz编程API几个重要接口,也是Quartz的重要组件
格式:[秒] [分] [时] [每月的第几日] [月] [每周的第几日] [年]
| 字段名 | 必须的 | 允许值 | 允许的特殊字符 |
|---|---|---|---|
| Seconds | YES | 0-59 | , - * / |
| Minutes | YES | 0-59 | , - * / |
| Hours | YES | 0-23 | , - * / |
| Day of month | YES | 1-31 | , - * ? / L W |
| Month | YES | 1-12 or JAN-DEC | , - * / |
| Day of week | YES | 1-7 or SUN-SAT | , - * ? / L # |
| Year | NO | empty, 1970-2099 | , - * / |
注意:有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推
特殊字符说明:
| 字符 | 含义 |
|---|---|
* | 用于 指定字段中的所有值。比如:* 在分钟中表示 每一分钟。 |
? | 用于 指定日期中的某一天,或是 星期中的某一个星期。 |
- | 用于 指定范围。比如:10-12 在小时中表示 10 点,11 点,12 点。 |
, | 用于 指定额外的值。比如:MON,WED,FRI 在日期中表示 星期一, 星期三, 星期五。 |
/ | 用于 指定增量。比如:0/15 在秒中表示 0 秒, 15 秒, 30 秒, 45 秒。5/15 在秒中表示 5 秒,20 秒,35 秒,50 秒。 |
L | 在两个字段中拥有不同的含义。比如:L 在日期(Day of month)表示 某月的最后一天。在星期(Day of week)只表示 7 或 SAT。但是,值L 在星期(Day of week)中表示 某月的最后一个星期几。比如:6L 表示 某月的最后一个星期五。也可以在日期(Day of month)中指定一个偏移量(从该月的最后一天开始).比如:L-3 表示 某月的倒数第三天。 |
W | 用于指定工作日(星期一到星期五)比如:15W 在日期中表示 到 15 号的最近一个工作日。如果第十五号是周六, 那么触发器的触发在 第十四号星期五。如果第十五号是星期日,触发器的触发在 第十六号周一。如果第十五是星期二,那么它就会工作开始在 第十五号周二。然而,如果指定 1W 并且第一号是星期六,那么触发器的触发在第三号周一,因为它不会 "jump" 过一个月的日子的边界。 |
L和 W | 可以在日期(day-of-month)合使用,表示 月份的最后一个工作日。 |
# | 用于 指定月份中的第几天。比如:6#3 表示 月份的第三个星期五(day 6 = Friday and "#3" = the 3rd one in the month)。其它的有,`2#1 表示 月份第一个星期一。4#5 表示 月份第五个星期三。注意: 如果只是指定 #5,则触发器在月份中不会触发。` |
注意:字符不区分大小写,MON 和 mon 相同。
cronExpression 示例
| 表达式 | 含义 |
|---|---|
0 0 12 * * ? | 每天中午 12 点 |
0 15 10 ? * * | 每天上午 10 点 15 分 |
0 15 10 * * ? | 每天上午 10 点 15 分 |
0 15 10 * * ? * | 每天上午 10 点 15 分 |
0 15 10 * * ? 2005 | 在 2005 年里的每天上午 10 点 15 分 |
0 * 14 * * ? | 每天下午 2 点到下午 2 点 59 分的每一分钟 |
0 0/5 14 * * ? | 每天下午 2 点到 2 点 55 分每隔 5 分钟 |
0 0/5 14,18 * * ? | 每天下午 2 点到 2 点 55 分, 下午 6 点到 6 点 55 分, 每隔 5 分钟 |
0 0-5 14 * * ? | 每天下午 2 点到 2 点 5 分的每一分钟 |
0 10,44 14 ? 3 WED | 3 月每周三的下午 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 L-2 * ? | 每月最后两天的上午10点15分 |
0 15 10 ? * 6L | 每月的最后一个星期五的上午 10 点 15 分 |
0 15 10 ? * 6L 2002-2005 | 2002 年到 2005 年每个月的最后一个星期五的上午 10 点 15 分 |
0 15 10 ? * 6#3 | 每月的第三个星期五的上午 10 点 15 分 |
0 0 12 1/5 * ? | 每月的 1 号开始每隔 5 天的中午 12 点 |
0 11 11 11 11 ? | 每年 11 月 11 号上午 11 点 11 分 |

导入依赖:
- <!--核心包-->
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>2.3.2</version>
- </dependency>
- <!--工具-->
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz-jobs</artifactId>
- <version>2.3.2</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.7</version>
- <scope>compile</scope>
- </dependency>
- package com.hzf.quartz.Job;
-
- import org.quartz.Job;
- import org.quartz.JobExecutionContext;
- import org.quartz.JobExecutionException;
-
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- /**
- * @ClassName HelloJob
- * @Description TODO
- * @Author Mr.Huang
- * @Date 2022/6/27 10:24
- * @Version 1.0
- **/
- public class HelloJob implements Job {
- //其实这里是可以操作数据库的,可以调用service业务的
- public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
- //输出当前时间
- Date date=new Date();
- SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- String dateString=dateFormat.format(date);
- //工作内容
- System.out.println("执行定时任务,时间是:"+dateString);
- }
- }
- package com.hzf.quartz.test;
-
- import com.hzf.quartz.Job.HelloJob;
- import org.quartz.*;
- import org.quartz.impl.StdSchedulerFactory;
-
- /**
- * @ClassName HelloSchedulerDemo
- * @Description TODO
- * @Author Mr.Huang
- * @Date 2022/6/27 10:28
- * @Version 1.0
- **/
- public class HelloSchedulerDemo {
- public static void main(String[] args) throws Exception{
- //1、创建调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)
- Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler();
- //2、任务实例(JobDetail)
- JobDetail jobDetail= JobBuilder.newJob(HelloJob.class) //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口
- .withIdentity("job1","group1") //参数1:任务的名称(唯一实例);参数2:任务组的名称
- .build();
- //3、创建触发器(Trigger)
- Trigger trigger= TriggerBuilder.newTrigger()
- .withIdentity("trigger1","group1") //参数1:触发器的名称(唯一实例);参数2:触发器组的名称
- .startNow() //马上启动触发器
- // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) //每5秒执行一次
- .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")) //使用cronExpression表达式
- .build();
- //4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
- scheduler.scheduleJob(jobDetail,trigger);
- //启动
- scheduler.start();
- }
- }

- <!--springboot版本-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-quartz</artifactId>
- </dependency>
- package com.hzf.quartz.config;
-
- import org.quartz.spi.TriggerFiredBundle;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
- import org.springframework.scheduling.quartz.AdaptableJobFactory;
- import org.springframework.stereotype.Component;
-
- /**
- * @ClassName MyAdaptableJobFactory
- * @Description TODO
- * @Author Mr.Huang
- * @Date 2022/6/27 11:27
- * @Version 1.0
- **/
- @Component("MyAdaptableJobFactory") //将该类实例化,使得可以直接用
- public class MyAdaptableJobFactory extends AdaptableJobFactory {
- //AutowireCapableBeanFactory可以将一个对象添加到Spring IOC容器中,并且完成该对象注入
- @Autowired
- private AutowireCapableBeanFactory autowireCapableBeanFactory;
-
- //该方法将实例化的任务对象手动的添加到SpringIOC容器中并且完成对象的注入
- @Override
- protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
- Object object = super.createJobInstance(bundle);
- //将object对象添加到Spring IOC容器中并完成注入
- this.autowireCapableBeanFactory.autowireBean(object);
- return object;
- }
- }
- package com.hzf.quartz.config;
-
- import com.hzf.quartz.service.QuartzService;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
- import org.springframework.scheduling.quartz.JobDetailFactoryBean;
- import org.springframework.scheduling.quartz.SchedulerFactoryBean;
- import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
-
- /**
- * Quartz(定时任务)配置类
- * @ClassName QuartzConfig
- * @Description TODO
- * @Author Mr.Huang
- * @Date 2022/6/27 10:53
- * @Version 1.0
- **/
- @Configuration
- public class QuartzConfig {
-
- /**
- * 1、创建Job对象
- */
- @Bean
- public JobDetailFactoryBean jobDetailFactoryBean(){
- JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();
- //关联我们自己的Job类
- factoryBean.setJobClass(QuartzService.class);
- return factoryBean;
- }
-
- /**
- * 2、创建Trigger对象
- * 使用setRepeatInterval
- */
- @Bean
- public SimpleTriggerFactoryBean simpleTriggerFactoryBean(@Qualifier("jobDetailFactoryBean") JobDetailFactoryBean jobDetailFactoryBean){
- SimpleTriggerFactoryBean factoryBean=new SimpleTriggerFactoryBean();
- //关联JobDetail对象
- factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
- //该参数表示一个执行的毫秒数
- factoryBean.setRepeatInterval(5000); //每隔5秒执行一次
- //重复次数
- factoryBean.setRepeatCount(5);
- return factoryBean;
- }
- /*
- * 创建Trigger对象
- * 功能描述:
- * 使用cronExpression表达式
- * @Param:
- * @Return:
- * @Author: Mr.Huang
- * @Date: 2022/6/27 15:04
- **/
- @Bean
- public CronTriggerFactoryBean cronTriggerFactoryBean(@Qualifier("jobDetailFactoryBean") JobDetailFactoryBean jobDetailFactoryBean){
- CronTriggerFactoryBean factoryBean=new CronTriggerFactoryBean();
- //关联JobDetail对象
- factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
- factoryBean.setCronExpression("0/5 * * * * ?"); //使用cronExpression表达式
- return factoryBean;
- }
-
- /**
- * 3、创建Scheduler,一个触发器可以执行多个任务
- * 参数1选择需要的bean类型
- * 参数2把自己注入好的JobFactory加入其中就可以访问数据库了
- */
- @Bean
- public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean simpleTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
- SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
- //关联trigger
- factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
- factoryBean.setJobFactory(myAdaptableJobFactory);
- return factoryBean;
- }
- }
- package com.hzf.quartz.service;
-
- import com.hzf.common.entity.User;
- import com.hzf.quartz.mapper.UserMapper;
- import org.quartz.Job;
- import org.quartz.JobExecutionContext;
- import org.quartz.JobExecutionException;
- import org.springframework.beans.factory.annotation.Autowired;
-
- import java.util.List;
-
- /**
- * 定时任务服务
- * @ClassName QuartzService
- * @Description TODO
- * @Author Mr.Huang
- * @Date 2022/6/27 11:25
- * @Version 1.0
- **/
- public class QuartzService implements Job {
- @Autowired
- private UserMapper userMapper;
-
- @Override
- public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
- List<User> users = userMapper.selectList(null);
- for (User user : users) {
- System.out.println(user.getUserName());
- }
- }
- }
- package com.hzf.quartz;
-
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.scheduling.annotation.EnableScheduling;
-
- /**
- * @ClassName QuartzApplication
- * @Description TODO
- * @Author Mr.Huang
- * @Date 2022/6/27 9:42
- * @Version 1.0
- **/
- @SpringBootApplication
- @EnableScheduling //开启定时任务
- @MapperScan("com.hzf.quartz.mapper")
- public class QuartzApplication {
- public static void main(String[] args) {
- SpringApplication.run(QuartzApplication.class,args);
- }
- }
- spring:
- application:
- name: quartz-service
- datasource:
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://xx.xxx.xxx.xx:3307/onlinebank?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
- username: root
- password: 123456
-
- server:
- port: 8085
-
- mybatis-plus:
- mapper-locations: classpath*:/mapper/*Mapper.xml
- configuration:
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- map-underscore-to-camel-case: true
- type-aliases-package: com.hzf.common.entity
