1 Quartz定时任务
Quartz 是一个完全由 Java 编写的开源任务调度框架,为在 Java 应用程序中进行任务调度提供了简单却强大的机制。
基于定时、定期的策略来执行任务是它的核心功能,比如x年x月的每个星期五上午8点到9点,每隔10分钟执行1次。
Quartz有5个核心要素:调度器(Scheduler)、任务(Job)、触发器(Trigger)、JobDetail、Calendar。
(1)Job(任务):是一个接口,有一个方法void execute(JobExecutionContext context),在实现接口的 execute 方法中编写所需要定时执行的 Job(任务),JobExecutionContext 类提供了调度应用的一些信息;Job 运行时的信息保存在 JobDataMap 实例中。
(2)JobDetail:Quartz每次执行job时,都重新创建一个Job实例,会接收一个Job实现类,以便运行的时候通过newInstance()的反射调用机制去实例化Job.JobDetail是用来描述Job实现类以及相关静态信息,比如任务在scheduler中的组名等信息。
(3)Trigger(触发器):描述触发Job执行的时间触发规则实现类SimpleTrigger和CronTrigger可以通过crom表达式定义出各种复杂的调度方案。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger 是最适合的选择;而 CronTrigger 则可以通过 Cron 表达式定义出各种复杂时间规则的调度方案:如工作日周一到周五的 15:00 ~ 16:00 执行调度等。
(4)Calendar:是一些日历特定时间的集合。一个Trigger可以和多个 calendar关联,比如每周一早上10:00执行任务,法定假日不执行,则可以通过calendar进行定点排除。
(5)Scheduler(调度器):代表一个Quartz的独立运行容器。Trigger和JobDetail可以注册到Scheduler中。Scheduler可以将Trigger绑定到某一JobDetail上,这样当Trigger被触发时,对应的Job就会执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job.
2 配置Maven依赖
<!--quartz定时任务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
3 实现Job(定时任务)
package com.job;
import cn.hutool.core.date.DateUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
public class QuartJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
before(context);
doExecute(context);
after(context, null);
} catch (Exception e) {
System.out.println("定时任务执行失败:" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
after(context, e);
}
}
/**
* 执行前
*
* @param context 工作执行上下文对象
*/
protected void before(JobExecutionContext context) {
System.out.println("------------");
System.out.println("开始执行定时任务:" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
}
/**
* 执行后
*
* @param context 工作执行上下文对象
*/
protected void after(JobExecutionContext context, Exception e) {
System.out.println("定时任务执行结束:" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
}
/**
* 执行方法
*
* @param context 工作执行上下文对象
* @throws Exception 执行过程中的异常
*/
protected void doExecute(JobExecutionContext context) throws Exception {
//获取JobDetail中关联的数据
String msg = (String) context.getJobDetail().getJobDataMap().get("msg");
System.out.println("定时任务正在执行中");
System.out.println("当前时间 :" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "\n" + msg);
}
}
4 创建QuartzConfig(生成定时任务实例和触发器)
package com.config;
import com.job.QuartJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
/**
* 创建Job实例
*
* @return
*/
@Bean
public JobDetail createJobDetail() {
return JobBuilder.newJob(QuartJob.class)//业务类
.withIdentity("QuartJob")//可以给该JobDetail起一个id
//每个JobDetail内都有一个Map,包含了关联到这个Job的数据,在Job类中可以通过context获取
.usingJobData("msg", "Hello Quartz! --旭东怪")//关联键值对
.storeDurably()//即使没有Trigger关联时,也不需要删除该JobDetail
.build();
}
/**
* 创建触发器
*
* @return
*/
@Bean
public Trigger createTrigger() {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/30 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(createJobDetail())//关联上述的JobDetail
.withIdentity("quartzTaskService")//给Trigger起个名字
.withSchedule(cronScheduleBuilder)
.build();
}
}