Quartz 调度器

Spring Boot 提供了多个方便使用 Quartz 调度器 的方法,包括 `spring-boot-starter-quartz` 启动器。如果 Quartz 可用,则会自动配置 `Scheduler`(通过 `SchedulerFactoryBean` 抽象)。

以下类型的 Bean 会被自动拾取并与 `Scheduler` 关联:

  • `JobDetail`:定义特定 Job。`JobDetail` 实例可以使用 `JobBuilder` API 构建。

  • 日历.

  • `Trigger`:定义何时触发特定 Job。

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

  • 属性

  • YAML

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

使用 JDBC 存储时,可以在启动时初始化模式,如下例所示:

  • 属性

  • YAML

spring.quartz.jdbc.initialize-schema=always
spring:
  quartz:
    jdbc:
      initialize-schema: "always"
默认情况下,数据库使用 Quartz 库提供的标准脚本进行检测和初始化。这些脚本会删除现有表,并在每次重启时删除所有触发器。也可以通过设置 `spring.quartz.jdbc.schema` 属性来提供自定义脚本。

要让 Quartz 使用非应用程序主 `DataSource` 的 `DataSource`,请声明一个 `DataSource` Bean,并使用 `@QuartzDataSource` 注解其 `@Bean` 方法。这样做可以确保 `SchedulerFactoryBean` 和模式初始化都使用特定于 Quartz 的 `DataSource`。类似地,要让 Quartz 使用非应用程序主 `TransactionManager` 的 `TransactionManager`,请声明一个 `TransactionManager` Bean,并使用 `@QuartzTransactionManager` 注解其 `@Bean` 方法。

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

Quartz 调度器的配置可以使用spring.quartz 属性和SchedulerFactoryBeanCustomizer bean 进行自定义,这些 bean 允许对 SchedulerFactoryBean 进行编程式的自定义。可以使用 spring.quartz.properties.* 自定义高级 Quartz 配置属性。

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

作业可以定义 setter 方法来注入数据映射属性。常规 bean 也能以类似的方式注入,如下例所示

  • Java

  • Kotlin

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)
	}

}