Java-Spring-Quartz使用总结

本文总结了Spring Boot中使用Quartz作为调度引擎的经验,包括1.5和2.0版本的集成差异。Spring Boot 2.0简化了配置,允许直接注入job和trigger启动调度。而在1.5版本中,需手动加载配置并监听Spring生命周期。文中提到了Quartz的工作原理,以及使用中遇到的坑,如job参数限制、非Spring管理bean问题、监听器持久化等,并给出了相应的解决方案。文章还介绍了如何配置持久化、创建不同类型的trigger以及监听器的创建和管理。

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

对于springboot来说,调度可以通过注释来启动一个简单的cron调度任务。

@Scheduled(cron = "0 0 3 * * ?") 

但是比较复杂的业务场景,就需要到调度引擎了,quartz就是一款优秀的调度引擎。

目前是试过两种spring版本的集成,1.5.9跟2.0.3版本,有所区别。

1.5的spring并没有提供专门的start启动类,所以很多东西都要自己手动写,而2.0提供有start,方便很多。

quartz工作原理:

schedule来调度一个任务,而任务由triggerjobdetail组成,jobdetail调用job来实现业务规则,借用一张图:

通常来讲,一个jobdetail和一个trigger是对应的,他们将设定同一个group名。trigger有简单trigger,也有cronTrigger,作用是指定触发规则(触发几次、间隔多少等)。而jobdetail用来指定一个job和部分调度规则,我们要把我们实现的业务规则写到job里面。jobdetail还有一个作用是给job传递一些参数(坑1:遗憾的是只有基础类型,你无法传递一个Object)。

坑2:很蛋疼的是,schedule的生成并不参与spring的bean生命周期管理,这意味着你无法在job里写业务规则的时候使用@autowire!为此,spring提供了专门的工厂类来解决这个问题。

除此之外,quartz还未trigger、job、schedule提供了响应的监听器,让你可以对他们的生命周期做出响应的处理,比如说一个任务触发前该做什么,触发后/结束后该做什么。

如果你将quartz设置为持久化到数据库中,那么以上的设定都是可以持久化的(坑3:低版本quartz的job分为静态非静态,静态job的jobdetail数据无法持久化到库中),除了监听器。

想让监听器在服务重启后一样有效的解决方法也很简单,配置一个全局的监听类就可以了,在监听类中可以用group来区别不同的调度类型,做出不同的处理。

坑4:cron类型的触发和简单触发似乎完全区别开,简单触发可以指定触发次数,而cron规则不能指定次数,要指定触发次数,似乎只能手动计数,然后在监听器中手动停掉。

Spring Boot 2.0的start集成方式:

yml配置

spring:
  quartz:
    #相关属性配置
    properties:
      org:
        quartz:
          scheduler:
            instanceName: quartzScheduler
            instanceId: AUTO
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

这个配置并没有实现持久化,也没有实现集群,是最简单的配置。

然后配置Job类,Job需要继承QuartzJobBean。

public class MyJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("任务启动");
    }
}

最后需要一个配置类QuartzConfiguration

@Configuration
public class QuartzConfiguration {
    @Bean
    public JobDetail myJobDetail() {
        return JobBuilder.newJob(MyJob.class).withIdentity("myJob").storeDurably().build();
    }

    // 把jobDetail注册到trigger上去
    @Bean
    public Trigger myJobTrigger() {
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(15).repeatForever();

        return TriggerBuilder.newTrigger()
                .forJob(myJobDetail())
                .withIdentity("myJobTrigger")
                .withSchedule(scheduleBuilder)
                .build();
    }
}

非常简洁,你不需要手动去启动调度,只需要像这样,把job、trigger注入,就可以使用了。调度会随着springboot的启动而启动。所以如果不是出于维护老项目的目的,趁早转Springboot2.0才是王道。

Spring Boot 1.5的使用就繁琐得多了:

首先我们需要一个配置类,可以命名为quartz.properties。虽然没有Spring官方starter支持,但是你也可以将这些配置写成yml文件的形式,但是这就需要你用@Vaule注释去手动读取注入了。

org.quartz.scheduler.instanceName=DefaultQuartzScheduler
#调度名称,全局可以有多个scheduler对象

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#线程池实现类,可以自定义,org.quartz.simpl.SimpleThreadPool是quartz自带的。

org.quartz.threadPool.threadCount=20
#可用于并发执行作业的线程数

org.quartz.threadPool.threadPriority=5
#线程权限值,1-10,默认为5

org.quartz.jobStore.misfireThreshold=60000
#用来设置调度引擎对触发器超时的忍耐时间,有可能任务触发时线程池已满或者调度挂了,但不超过这个时间就不算超时。

org.quartz.jobStore.class= org.quartz.impl.jdbcjobstore.JobStoreTX
#指定使用的JobStore,有org.quartz.simpl.RAMJobStore和org.quartz.impl.jdbcjobstore.JobStoreTX,前者代表数据存于内存中,后者代表持久化到数据库。

org.quartz.jobStore.useProperties=false
#若为true,则JobDataMaps中的所有值都将是String类型,false就可以使用所有基本类型。

org.quartz.jobStore.driverDelegateClass= org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
#不同的数据库对应不同的DriverDelegate

org.quartz.jobStore.tablePrefix=qrtz_
#表前缀,这将体现在数据库表名上

org.quartz.jobStore.dataSource=qzDS
#设置JobStore应该使用哪个DataSource,这对应着dataSource后面的那个属性名

org.quartz.dat
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值