什么是Quartz

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:

  • 持久性作业 - 就是保持调度定时的状态;
  • 作业管理 - 对调度作业进行有效的管理;

在实际项目开发中,随着业务的增大,需要操作Job的也就越多,肯定不能是人工操作,我们需要应该自动调度的任务框架去解决,功能的具体实现如下:

  1. 首先我们需要定义实现一个定时功能的接口,我们可以称之为Task或者Job(Quartz中称之为Job),如定时发送邮件Job,优惠卷到期通知Job,实现如下:

    image-20180710135410275
  2. 有了Job之后,我们需要一个能触发Job并执行的触发器(Trigger),Trigger最基本的功能是指定Job的执行时间,执行间隔,运行次数等。

    image-20180710135421739
  3. 有了Job和Trigger后,需要一个Schedule,来指定Trigger去执行指定的Job。

    image-20180710135431806

上面三个部分就是Quartz的基本组成部分:

  • 调度器:Scheduler
  • 任务:JobDetail
  • 触发器:Trigger,包括SimpleTrigger和CronTrigger

Quartz在SpringBoot的应用

  1. 使用Maven添加依赖

    <!-- SpringBoot 整合 Quartz 定时任务 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
        <version>2.3.5.RELEASE</version>
    </dependency>
  2. 配置yml

    spring:
      quartz:
        scheduler-name: communityScheduler//scheduler名称
        job-store-type: jdbc//持久化方法
  3. 实现Job接口,实现定时任务逻辑

    public class AlphaJob implements Job {
        //实现Job接口
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println(Thread.currentThread().getName()+": execute a quartz job.");
        }
    }
  4. 配值定时任务,创建一个Config类,设置

    //配置-》数据库-》调用
    //Quartz 定时任务配置类
    @Configuration
    public class QuartzConfig {
        //FactoryBean可简化Bean的实例化过程:
        //1.通过FactoryBean封装Bean的实例化过程
        //2.将FactoryBean封装到Spring容器中
        //3.将FactoryBean注入给其他的Bean
        //4.该Bean得到的是FactoryBean所管理的对象实例
    
        // 配置JobDetail
        @Bean
        public JobDetailFactoryBean alphaJobDetail(){
            JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
            factoryBean.setJobClass(AlphaJob.class);
            factoryBean.setName("alphaJob");//设置名称
            factoryBean.setGroup("alphaJobGroup");//设置分组
            factoryBean.setDurability(true);//是否持久(数据库中是否删除)
            factoryBean.setRequestsRecovery(true);//是否可恢复
            return factoryBean;
        }
    
        // 配置Trigger(SimpleTriggerFactoryBean(简单任务用,按指定的时间间隔执行多少次任务的情况),CronTriggerFactoryBean(复杂任务用,通过Cron表达式来控制任务的执行时间))
        @Bean
        public SimpleTriggerFactoryBean alphaTrigger(JobDetail alphaJobDetail){
            SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
            factoryBean.setJobDetail(alphaJobDetail);//关联上述JobDetail
            factoryBean.setName("alphaTrigger");//设置名称
            factoryBean.setGroup("alphaTriggerGroup");//设置分组
            factoryBean.setRepeatInterval(3000);//设置执行的时间间隔
            factoryBean.setJobDataMap(new JobDataMap());
            return factoryBean;
        }
    }

    JobDetail绑定指定的Job,每次调用时,首先会拿到对应的JobDetail,然后创建Job实例,在去执行Job中execute()中的内容,任务结束后,关联的Job对象实例会被释放,且会被JVM GC清除。

    为什么设计成JobDetail+Job,不直接使用Job

    JobDetail定义的是任务数据,而真正执行逻辑在Job中

    如果直接使用Job,就会存在对同一个Job实例并发访问的问题,而JobDetail + Job方式,每次执行时,都会根据JobDetail创建一个新Job实例,这样可以避免并发问题

到此为止,Scheduler会在底层自动调用我们上面定义的定时任务。

参考:

官网:http://www.quartz-scheduler.org/

Cron表达式:https://cron.qqe2.com/

文章:https://blog.csdn.net/noaman_wgs/article/details/80984873

文章:https://www.jianshu.com/p/06c4307214b7