Quartz スケジューラー

Spring Boot は、spring-boot-starter-quartz スターターなど、Quartz スケジューラー (英語) を操作するための便利な機能をいくつか提供します。Quartz が使用可能な場合は、Scheduler が自動的に構成されます (SchedulerFactoryBean 抽象化を通じて)。

次の型の Bean が自動的に取得され、Scheduler に関連付けられます。

  • JobDetail: 特定のジョブを定義します。JobDetail インスタンスは、JobBuilder API を使用して構築できます。

  • Calendar.

  • Trigger: 特定のジョブがいつトリガーされるかを定義します。

デフォルトでは、インメモリ 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 を宣言し、@Bean メソッドに @QuartzDataSource アノテーションを付けます。そうすることで、Quartz 固有の DataSource が SchedulerFactoryBean とスキーマの初期化の両方で使用されるようになります。同様に、Quartz にアプリケーションのメイン TransactionManager 以外の TransactionManager を使用させるには、TransactionManager Bean を宣言し、@Bean メソッドに @QuartzTransactionManager アノテーションを付けます。

デフォルトでは、構成によって作成されたジョブは、永続ジョブストアから読み取られた登録済みのジョブを上書きしません。既存のジョブ定義の上書きを有効にするには、spring.quartz.overwrite-existing-jobs プロパティを設定します。

Quartz スケジューラー構成は、spring.quartz プロパティおよび SchedulerFactoryBeanCustomizer Bean を使用してカスタマイズできます。これにより、プログラムによる SchedulerFactoryBean のカスタマイズが可能になります。spring.quartz.properties.* を使用して、高度な Quartz 構成プロパティをカスタマイズできます。

特に、Quartz は spring.quartz.properties を介してスケジューラーを構成する方法を提供するため、Executor Bean はスケジューラーに関連付けられていません。タスクエグゼキュータをカスタマイズする必要がある場合は、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)
	}

}