Quartz 调度器

Spring Boot 为使用 Quartz 调度器 提供了多种便利,包括 spring-boot-starter-quartz Starters。 如果 Quartz 可用,则会通过 SchedulerFactoryBean 抽象自动配置一个 Schedulerspring-doc.cadn.net.cn

以下类型的 Bean 会被自动拾取并与 Scheduler 关联:spring-doc.cadn.net.cn

默认情况下,使用的是内存型 JobStore。 但是,如果您的应用程序中存在 DataSource Bean,并且相应地配置了 spring.quartz.job-store-type 属性,则可以配置基于 JDBC 的存储,如下例所示:spring-doc.cadn.net.cn

spring.quartz.job-store-type=jdbc
spring:
  quartz:
    job-store-type: "jdbc"

使用 JDBC 存储时,可以在启动时初始化数据库模式,如下例所示:spring-doc.cadn.net.cn

spring.quartz.jdbc.initialize-schema=always
spring:
  quartz:
    jdbc:
      initialize-schema: "always"
默认情况下,数据库会使用 Quartz 库提供的标准脚本进行检测和初始化。 这些脚本会在每次重启时删除现有表,从而清除所有触发器。 若要使用自定义脚本,请设置 spring.quartz.jdbc.schema 属性。 某些标准脚本(例如用于 SQL Server、Azure SQL 和 Sybase 的脚本)在未经修改的情况下无法直接使用。 在这种情况下,请复制该脚本并根据脚本中的注释进行编辑,然后将 spring.quartz.jdbc.schema 设置为指向您自定义的脚本。

要使 Quartz 使用不同于应用程序主 DataSourceDataSource,请声明一个 DataSource Bean,并使用 @QuartzDataSource 注解其 @Bean 方法。 这样做可确保 Quartz 特定的 DataSource 同时被 SchedulerFactoryBean 和架构初始化所使用。 类似地,要使 Quartz 使用不同于应用程序主 TransactionManagerTransactionManager,请声明一个 TransactionManager Bean,并使用 @QuartzTransactionManager 注解其 @Bean 方法。spring-doc.cadn.net.cn

默认情况下,通过配置创建的作业不会覆盖从持久化作业存储中读取的已注册作业。 要启用覆盖现有作业定义的功能,请设置 spring.quartz.overwrite-existing-jobs 属性。spring-doc.cadn.net.cn

Quartz 调度器配置可以使用 spring.quartz 属性和 SchedulerFactoryBeanCustomizer Bean 进行自定义,从而允许以编程方式通过 SchedulerFactoryBean 进行自定义。 高级 Quartz 配置属性可以使用 spring.quartz.properties.* 进行自定义。spring-doc.cadn.net.cn

特别是,Executor Bean 不与调度器关联,因为 Quartz 提供了一种通过 spring.quartz.properties 配置调度器的方法。 如果您需要自定义任务执行器,请考虑实现 SchedulerFactoryBeanCustomizer

作业(Jobs)可以定义 setter 方法来注入数据映射(data map)属性。 普通 Bean 也可以通过类似的方式进行注入,如下例所示:spring-doc.cadn.net.cn

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import org.springframework.scheduling.quartz.QuartzJobBean;

public class MySampleJob extends QuartzJobBean {

	// fields ...

	private MyService myService;

	private String name;


	// Inject "MyService" bean
	public void setMyService(MyService myService) {
		this.myService = myService;
	}

	// Inject the "name" job data property
	public void setName(String name) {
		this.name = name;
	}

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		this.myService.someMethod(context.getFireTime(), this.name);
	}

}
import org.quartz.JobExecutionContext
import org.springframework.scheduling.quartz.QuartzJobBean

class MySampleJob : QuartzJobBean() {

	// fields ...

	private var myService: MyService? = null

	private var name: String? = null

	// Inject "MyService" bean
	fun setMyService(myService: MyService?) {
		this.myService = myService
	}

	// Inject the "name" job data property
	fun setName(name: String?) {
		this.name = name
	}

	override fun executeInternal(context: JobExecutionContext) {
		myService!!.someMethod(context.fireTime, name)
	}

}