Quartz 排程器

Spring Boot 提供了多種便利功能,可與 Quartz 排程器 搭配使用,包括 spring-boot-starter-quartz Starter。如果 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 方法。

預設情況下,透過組態建立的 Job 不會覆寫已從持久性 Job 儲存讀取的已註冊 Job。若要啟用覆寫現有的 Job 定義,請設定 spring.quartz.overwrite-existing-jobs 屬性。

可以使用 spring.quartz 屬性和 SchedulerFactoryBeanCustomizer Bean 自訂 Quartz 排程器組態,這些 Bean 允許程式化的 SchedulerFactoryBean 自訂。可以使用 spring.quartz.properties.* 自訂進階 Quartz 組態屬性。

特別是,Executor Bean 未與排程器關聯,因為 Quartz 提供了一種透過 spring.quartz.properties 組態排程器的方法。如果您需要自訂任務執行器,請考慮實作 SchedulerFactoryBeanCustomizer

Job 可以定義 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)
	}

}