springboot集成quartz(一)基础概念

本文主要介绍Spring Boot集成Quartz的相关内容。先阐述了Quartz的基本概念,包括Job、Trigger、Scheduler及监听器等,详细说明了各部分的作用、属性和使用方法,如Job的执行逻辑、Trigger的常用类型等。最后给出了完整代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot集成quartz

一,quartz基本概念

1.Job

Job,JobDetail,JobBuilder,JobExecutionContext

Job?

job英文单词的意思就是工作,意味着你需要调度器具体要做的事情,job是一个工作任务调度的接口,具体要被调度的任务要实现该接口,重写该接口定义的execute方法(具体任务)编写任务的业务逻辑。

job实例在Quartz中的生命周期:每次调度器执行job时,他在调用execute方法前都会创建一个job实例,调用方法完成后,关联的job实例被释放,然后垃圾回收。(即每次job的构造方法都会被执行)

jobDetail?

通过传入job类型,JobBuilder会产生jobDetail实例,jobDetail存储着该类型的job的一些实例信息,调度器需要借助jobDetail来添加job实例

重要信息:

  • name:任务名称
  • group:任务组名称(会有默认组名)
  • jobDataMap

JobExecutionContext?

调度器在调用一个job的execute方法时,会将JobExecutionContext传递给该方法,job通过该JobExecutionContext对象可以访问到Quartz运行时候得环境和job本身的明细数据(job带有的信息)

JobBuilder?

jobDetail生成器

补充
  • @DisallowConcurrentExecution:相同的jobDetail不能并发执行,不同的jobDetail可以并发执行,

  • @PersistJobDataAfterExecution:将该注解加在job类上,告诉Quartz在成功执行了job类的execute方法后(没有发生任何异常),更新JobDetail中JobDataMap的数据,使得该job(即JobDetail)在下一次执行的时候,JobDataMap中是更新后的数据,而不是更新前的旧数据

示例:

        //由job类生产jobDetail
        JobDetail jobDetail = newJob(TestJob.class) //产生Job实例,job信息存储在jobDetail中
                .usingJobData("key1","val1")//通过jobDataMap为job实例增加属性,然后再传递到调度器中去
                .usingJobData("key2","val2")
                .withIdentity("helloTask","task1")
                .build();//由jobBuilder生成jobDetail

2.Trigger

触发器

相关属性
  • jobKey属性:当trigger触发时被执行的job的身份;
  • startTime属性:设置trigger第一次触发的时间;该属性的值是java.util.Date类型,表示某个指定的时间点
  • endTime属性:表示trigger失效的时间点。
  • 优先级(priority)如果你的trigger很多(或者Quartz线程池的工作线程太少),Quartz可能没有足够的资源同时触发所有的trigger;这种情况下,你可能希望控制哪些trigger优先使用Quartz的工作线程,要达到该目的,可以在trigger上设置priority属性。比如,你有N个trigger需要同时触发,但只有Z个工作线程,优先级最高的Z个trigger会被首先触发。如果没有为trigger设置优先级,trigger使用默认优先级,值为5;priority属性的值可以是任意整数,正数、负数都可以。注意:只有同时触发的trigger之间才会比较优先级。10:59触发的trigger总是在11:00触发的trigger之前执行。如果trigger是可恢复的,在恢复后再调度时,优先级与原trigger是一样的。
常用的触发器
SimpleTrigger

SimpleTrigger可以满足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行,并且以指定的间隔重复执行若干次。

示例:

        //SimpleTrigger
        SimpleTrigger simpleTrigger = (SimpleTrigger) newTrigger()
                .withIdentity("trigger1","group1")//触发器标识
                .startAt(startTime)//开始触发时间
                .forJob("helloTask","task1")//绑定的任务组
                .withSchedule(simpleSchedule()//调度设定
                    .withRepeatCount(10)//重复次数
                    .withIntervalInMilliseconds(10))//执行频率
                .endAt(endTime)//结束时间
                .build();
CronTrigger

CronTrigger通常比Simple Trigger更有用,如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。使用CronTrigger,您可以指定号时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。
即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

CronTrigger重点就是cron表达式,类似于spring自带的定时器中的cron表达式
可以参考这个:spring自带定时器

示例:

        //CronTrigger
        CronTrigger cronTrigger = (CronTrigger) newTrigger()
                .withIdentity("trigger2","group2")//触发器标识
                .startAt(startTime)//开始触发时间
                .forJob("helloTask1","task2")//绑定的任务组
                .withSchedule(cronSchedule("0 42 10 * * ?")//cron表达式 --- 每天10点42分执行
                        .withMisfireHandlingInstructionFireAndProceed())//错过触发 -- 一般是智能模式
                .endAt(endTime)//结束时间
                .build();

3.Scheduler

配置好任务器和触发器就可以开始调度了

调度器工厂(SchedulerFactory)

所有的调度器示例都需要经过SchedulerFactory创建,而SchedulerFactory是根据quartz.properties文件定义的属性来创建和初始化Quartz Scheduler


org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000

org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore

示例:

        //获取调度工厂
        SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
        //从工厂中获取调度器
        Scheduler sched = schedFact.getScheduler();
        //开始调度
        sched.start();
        //挂起
        //sched.standby();
        //关闭任务调度
        //1.等待当前任务执行完毕在关闭任务调度
        //sched.shutdown(true);
        //2.直接关闭任务调度
        //sched.shutdown(false);
        //传入调度任务和任务触发器
        sched.scheduleJob(jobDetail,simpleTrigger);

监听器

1.任务监听器
/**
 * @Description:    任务监听器
 * @Author:         Kevin
 * @CreateDate:     2019/5/8 2:37
 * @UpdateUser:     Kevin
 * @UpdateDate:     2019/5/8 2:37
 * @UpdateRemark:   修改内容
 * @Version: 1.0
 */
public class TestJobListener implements JobListener {

    /**
     * 获取监听器名
     * @return
     */
    @Override
    public String getName() {
        return null;
    }

    /**
     * 执行任务前调用
     * @param jobExecutionContext
     */
    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {

    }

    /**
     * 执行任务前,但是该任务被拒绝执行时调用
     * @param jobExecutionContext
     */
    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {

    }

    /**
     * 执行任务后调用
     * @param jobExecutionContext
     * @param e
     */
    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {

    }
}

配置监听器

        //全局任务监听配置
        sched.getListenerManager().addJobListener(new TestJobListener(), EverythingMatcher.allJobs());
        //局部任务监听配置
        sched.getListenerManager().addJobListener(new TestJobListener(), KeyMatcher.keyEquals(new JobKey("helloTask","task1")));

触发器监听器和调度器监听器使用和配置方法十分相似,省略不写

完整代码:

    public static void test(Date startTime,Date endTime) throws SchedulerException {
        //由job类生产jobDetail
        JobDetail jobDetail = newJob(TestJob.class) //产生Job实例,job信息存储在jobDetail中
                .usingJobData("key1","val1")//通过jobDataMap为job实例增加属性,然后再传递到调度器中去
                .usingJobData("key2","val2")
                .withIdentity("helloTask","task1")
                .build();//由jobBuilder生成jobDetail

        //SimpleTrigger
        SimpleTrigger simpleTrigger = (SimpleTrigger) newTrigger()
                .withIdentity("trigger1","group1")//触发器标识
                .startAt(startTime)//开始触发时间
                .forJob("helloTask","task1")//绑定的任务组
                .withSchedule(simpleSchedule()//调度设定
                    .withRepeatCount(10)//重复次数
                    .withIntervalInMilliseconds(10))//执行频率
                .endAt(endTime)//结束时间
                .build();

        //CronTrigger
        CronTrigger cronTrigger = (CronTrigger) newTrigger()
                .withIdentity("trigger2","group2")//触发器标识
                .startAt(startTime)//开始触发时间
                .forJob("helloTask1","task2")//绑定的任务组
                .withSchedule(cronSchedule("0 42 10 * * ?")//cron表达式 --- 每天10点42分执行
                        .withMisfireHandlingInstructionFireAndProceed())//错过触发 -- 一般是智能模式
                .endAt(endTime)//结束时间
                .build();

        //获取调度工厂
        SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
        //从工厂中获取调度器
        Scheduler sched = schedFact.getScheduler();
        //开始调度
        sched.start();
        //挂起
        //sched.standby();
        //关闭任务调度
        //1.等待当前任务执行完毕在关闭任务调度
        //sched.shutdown(true);
        //2.直接关闭任务调度
        //sched.shutdown(false);
        //传入调度任务和任务触发器
        sched.scheduleJob(jobDetail,simpleTrigger);

        //全局任务监听配置
        sched.getListenerManager().addJobListener(new TestJobListener(), EverythingMatcher.allJobs());
        //局部任务监听配置
        sched.getListenerManager().addJobListener(new TestJobListener(), KeyMatcher.keyEquals(new JobKey("helloTask","task1")));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值