Quartz是一个定时任务框架,相较于JDK和Spring的定时任务线程池,其功能更加多样,调度更加灵活,而且更适合分布式系统(因为引入了数据库)。
核心组件
- Scheduler:调度器。控制任务调度
- Trigger: 触发器。决定什么时候来执行任务。
- JobDetail :定义任务细节
- Job:任务的执行逻辑
代码示例
首先引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
编写任务逻辑代码
@Component
public class MessageDayJob implements Job {
@Autowired
QuartzServiceImpl quartzService;
private int intervalDay = 30;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("执行任务");
// 任务的具体逻辑
quartzService.insertMessageHis(intervalDay);
quartzService.deleteMessage(intervalDay);
}
}
定义任务
@Configuration
public class QuartzConfig {
@Bean
public JobDetailFactoryBean messageJobDetail(){
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(MessageDayJob.class);
factoryBean.setName("messageJob");
factoryBean.setGroup("messageJobGroup");
factoryBean.setDurability(true);// 持续保存
factoryBean.setRequestsRecovery(true);
return factoryBean;
}
@Bean
public CronTriggerFactoryBean messageTrigger(JobDetail messageJobDetail){
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
factoryBean.setJobDetail(messageJobDetail);
factoryBean.setName("messageTrigger");
factoryBean.setGroup("messageTriggerGroup");
factoryBean.setCronExpression("0 0 2 * * ?");// 每天凌晨2点执行
factoryBean.setJobDataMap(new JobDataMap());
return factoryBean;
}
}
在上述代码中,我们并没有编写数据库相关配置。Quartz会默认将任务数据保存到JVM内存中,但是当服务器挂了后,任务数据就会消失。而且,在服务器集群中,该数据难以统一。所以我们需要引入数据库。
srping:
quartz:
# 将任务等保存化到数据库
job-store-type: jdbc
# 程序结束时会等待quartz相关的内容结束
wait-for-jobs-to-complete-on-shutdown: true
# QuartzScheduler启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录
overwrite-existing-jobs: true
# 这里居然是个map,搞得智能提示都没有,佛了
properties:
org:
quartz:
# scheduler相关
scheduler:
# scheduler的实例名
instanceName: scheduler
instanceId: AUTO
# 持久化相关
jobStore:
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 表示数据库中相关表是QRTZ_开头的
tablePrefix: QRTZ_
useProperties: false
# 线程池相关
threadPool:
class: org.quartz.simpl.SimpleThreadPool
# 线程数
threadCount: 10
# 线程优先级
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true