SpringBoot整合Quartz


前言

知识概念

一、什么是Quartz?

Quartz是一个完全由java编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。

二、Quartz架构


Quartz架构有4个核心概念:Job JobDetail Trigger Scheduler
Job:表示一个工作或任务,包含具体执行的内容。
JobDetail:表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
Trigger:表示触发器,包含可执行调度程序的时间参数配置,是可执行调度程序的时间执行策略
Scheduler:代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger,当JobDetail和Trigger组合,就可以被调度容器调度了

三、示例


框架:Springboot;  (quartz官方Demo)
Pom.xml
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
</dependency>
quartz.properties
//Quartz
//线程调度器实例名
org.quartz.scheduler.instanceName = quartzScheduler
//如何存储任务和触发器等信息
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
//驱动代理
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
//表前缀
org.quartz.jobStore.tablePrefix = qrtz_ 
//数据源  must
org.quartz.jobStore.dataSource = quartzDataSource
//是否集群
org.quartz.jobStore.isClustered = false

org.quartz.dataSource.quartzDataSource.connectionProvider.class=com.alibaba.druid.support.quartz.DruidQuartzConnectionProvider
org.quartz.dataSource.quartzDataSource.driverClassName =com.mysql.jdbc.Driver
org.quartz.dataSource.quartzDataSource.Url=jdbc:mysql://localhost:3306/quartz?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
org.quartz.dataSource.quartzDataSource.username=root
org.quartz.dataSource.quartzDataSource.password=root
org.quartz.dataSource.quartzDataSource.validationQuery=SELECT 1 FROM DUAL 
//线程池的线程数    must>0 
org.quartz.threadPool.threadCount = 3

1、Job
public class BarrageJob implements Job{

    private static Logger logger = Logger.getLogger(BarrageJob.class);

    @Autowired
    BarrageService barrageService;
    @Autowired
    QuartzService quartzService;

    //任务的具体执行内容
    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        logger.info("BarrageJob开始执行");
        Date date = new Date();
        Timestamp time = new Timestamp(date.getTime());
        Integer count = barrageService.getBarrageCount(time);
        quartzService.insertJobData(new QrtzJobData(-1,context.getJobDetail().getKey().getName(),time,String.valueOf(count),BarrageJob.class.getName()));
        logger.info("BarrageJob执行完毕");
    }
}
注意:BarrageJob中的注解正常情况下是无效的,因为它没有被Spring容器管理,因此需要在下面手动注入到容器中。
2、JobDetail
JobDetail myjob = JobBuilder.newJob(BarrageJob.class).withIdentity(jobName, jobGroupName).build();
3、Trigger
Quartz提供了多个Trigger供我们选择(详情请查看相关源码),可以选择其一例如:CronTrigger
CronTrigger trigger = TriggerBuilder.newTrigger().
            withSchedule(CronScheduleBuilder.cronSchedule(Cron表达式).withIdentity(triggerName, triggerGroup).startAt(开始时间).endAt(结束时间).build();
Cron表达式规则可以自行百度
4、Scheduler
ScheduleConfig:
@Configuration
public class ScheduleConfig {
    //添加工作监听如不需要可注释    
    @Autowired
    MyJobListener myJobListener;
    //注册此工厂是为了使得在任务或工作即Job中也能使用Spring注解
    @Autowired
    MyJobFactory myJobFactory;
    @Bean
    public SchedulerFactoryBean getSchedulerFactoryBean(){
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setJobFactory(myJobFactory);
        Properties quartzProperties = ReadResourceUtils.getProperties("quartz.properties");
        //可以选择不加载自定义的properties文件,系统会加载默认的配置文件
        if(null != quartzProperties)factory.setQuartzProperties(quartzProperties);
        return factory;
    }
    @Bean(name="myScheduler")
    public  Scheduler getScheduler() throws SchedulerException{
        //SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = getSchedulerFactoryBean().getScheduler();
        scheduler.getListenerManager().addJobListener(myJobListener);
        return scheduler;
    }

}
MyJobFactory:
@Component
public class MyJobFactory extends AdaptableJobFactory{
    @Autowired
    private AutowireCapableBeanFactory factory;
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        // 调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入
        factory.autowireBean(jobInstance);
        return jobInstance;
    }
}
MyJobListener:
@Component
public class MyJobListener implements JobListener {

    @Override
    public String getName() {
        return "myJobListener";
    }
    @Autowired
    QuartzService quartzService;
    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        System.out.println("start:jobToBeExecuted");
        String jobName = context.getJobDetail().getKey().getName();
        System.out.println("end:jobToBeExecuted");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {

    }
    /**任务执行后更新任务状态*/
    @Override
    public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException) {
        System.out.println("start:jobWasExecuted");
        String jobName = context.getJobDetail().getKey().getName();
        System.out.println("end:jobWasExecuted");
    }

}
5、绑定JobDetail和CronTrigger到scheduler容器中
因为上面scheduler配置的时候已经将scheduler交给Spring容器进行管理了此时只需要自动注入
就可以获得scheduler容器
//将JobDetail和CronTrigger绑定到scheduler容器中
scheduler.scheduleJob(JobDetail, CronTrigger);
//调度任务
scheduler.start();

三、总结

使用Quartz首先要理解它的4大核心概念,接着理清楚它的流程就可以很快掌握