多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
Quartz是OpenSymphony开源组织在工作计划-定时任务领域的另一个开源项目。它是完全由Java开发的,可用于执行预定任务。它类似于java.util.Timer定时器。但是与timer相比,quartz增加了许多功能。 ## 一、 引入对应的 maven依赖 在 springboot2.0 后官方添加了 Quartz 框架的依赖,所以只需要在 pom 文件当中引入 ~~~ <!--引入quartz定时框架--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ~~~ ## 二、 创建一个任务类Job 首先,我们需要定义一个接口来实现计时功能。我们可以将其称为任务(或任务),例如:定期发送电子邮件的任务,重新启动机器的任务以及在优惠券到期时发送SMS提醒的任务。 ![](https://img.kancloud.cn/54/36/543614485c5e5761517bcac570bacf3a_1654x922.png) 由于 springboot2.0 自动进行了依赖所以创建的定时任务类直接继承 QuzrtzJobBean 就可以了,新建一个定时任务类:QuartzSimpleTask ~~~ public class QuartzSimpleTask extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("quartz简单的定时任务执行时间:"+new Date().toLocaleString()); } } ~~~ ## 三、创建 Quartz 定时配置类 还需要一个可以触发任务执行的触发器。触发器触发器的基本功能是指定作业的执行时间,执行间隔和运行时间。 ![](https://img.kancloud.cn/a3/8b/a38b5ea0f2d7fa8a352f410313044572_1840x808.png) 如何结合工作与触发?也就是说,如何分配触发器以执行指定的作业?此时,需要一个Schedule来实现此功能。 ![](https://img.kancloud.cn/2a/87/2a87b9414b244ec05ed9bc804178bb4a_1360x538.png) 将之前创建的定时任务添加到定时调度里面 ~~~ @Configuration public class QuartzSimpleConfig { //指定具体的定时任务类 @Bean public JobDetail uploadTaskDetail() { return JobBuilder.newJob(QuartzSimpleTask.class) .withIdentity("QuartzSimpleTask") .storeDurably().build(); } @Bean public Trigger uploadTaskTrigger() { //这里设定触发执行的方式 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/5 * * * * ?"); // 返回任务触发器 return TriggerBuilder.newTrigger().forJob(uploadTaskDetail()) .withIdentity("QuartzSimpleTask") .withSchedule(scheduleBuilder) .build(); } } ~~~ 最后运行项目查看效果,"\*/5 \* \* \* \* ?"表示定时任务,每隔5秒钟执行一次。 ## 四、深入解析 ### 4.1.核心概念 * **Job**:一个仅包含一个`void execute(JobExecutionContext context)`Abstract方法的简单接口。在实际开发中,要执行的任务是通过实现接口自定义实现的。`JobExecutionContext`提供调度上下文信息。 ~~~ public interface Job { void execute(JobExecutionContext context) throws JobExecutionException; } ~~~ * **JobDetail**:包含多个构造函数,最常用的是`JobDetail(String name, String group, Class jobClass)`Jobclass是实现作业接口的类,name是调度程序中任务的名称,group是调度程序中任务的组名。默认组名称为`Scheduler.DEFAULT_GROUP`。 * **Trigger**:描述触发作业执行的时间规则的类。包含: 1. **SimpleTrigger**:一次或固定间隔时间段的触发规则。 2. **CronTrigger**:通过cron表达式描述更复杂的触发规则。 * **Calendar**:Quartz 提供的**Calendar**类。触发器可以与多个Calendar关联以排除特殊日期。 * **Scheduler**:代表独立于Quartz 的运行容器。在Scheduler 中注册了Trigger和JobDetail。它们在调度程序中具有自己的名称(名称)和组名称(Group)。触发器和JobDetail名称和组名称的组合必须唯一,但是触发器名称和组名称的组合可以与JobDetail相同。一个Job可以绑定到多个触发器,也可以不绑定。 * * * Job还具有一个子接口:statefuljob,这是一个没有方法的标签接口,表示有状态任务。 1. 无状态任务:它具有jobdatamap复制,因此可以并发运行; 2. 有状态任务statefuljob:共享一个jobdatamap,并且将保存对jobdatamap的每次修改。因此,前一个有statefuljob将阻止下一个statefuljob。 ### 4.2.SimpleTrigger and CronTrigger * **SimpleTrigger**可以在指定的时间段内执行一个Job任务,也可以在一个时间段内多次执行。 * **CronTrigger**功能非常强大,它基于Calendar进行作业调度,并且可以比simpletrigger更精确地指定间隔,因此crotrigger比simpletrigger更常用。Crotrigger基于cron表达式。 首先,让我们了解cron表达式: 由七个子表达式组成的字符串的格式如下: **\[秒\] \[分钟\] \[小时\] \[天\] \[月\] \[周\] \[年\]** 例如:`00:00:00?\* 10,11,12 1#5 2018`,表示2018年10月,11月和12月的第一周星期五的00:00:00。看上去不是很容易书写与记忆,但是我们可以通过网络上的在线Cron表达式生成工具,来帮助我们写表达式:**在线生成cron表达式的工具:http:[//cron.qqe2.com/](https://cron.qqe2.com/)** | 位置 | 时间域名 | 容许值 | 允许特殊字符 | | --- | --- | --- | --- | | 1个 | 秒 | 0-59 | ,– \* / | | 2 | 分钟 | 0-59 | ,– \* / | | 3 | 小时 | 0-23 | ,– \* / | | 4 | 日期 | 1-31 | ,– \*?/ | | 5 | 月 | 1-12 | ,– \* / | | 6 | 周 | 1-7 | ,– \*?/ | | 7 | 年份(可选) | 空1970-2099 | ,– \* / | 特殊字符的含义如下: * 星号(\*):可在所有字段中使用以指示相应时域中的每次时间。例如,分钟字段中的\*表示“每分钟”; * 问号(?):此字符仅在日期和星期字段中使用。通常将其指定为“无意义的值”,等同于点字符; * 减号(-):表示范围。如果在小时字段中使用“ 10-12”,则表示10到12,即10、11、12; * 逗号(,):表示列表值。如果在星期字段中使用“星期一,星期三,星期五”,则表示星期一,星期三和星期五; * 斜线(/):X / Y表示相等的步长序列,其中X为起始值,y为增量步长值。如果在分钟字段中使用0/15,则表示0、15、30和45秒,而5/15在分钟字段中表示5、20、35、50,也可以使用\* / y,这等效到0 / y;