@Scheduled アノテーションで定期実行

このガイドでは、Spring を使用してタスクをスケジュールする手順を説明します。

構築するもの

Spring Framework の @Scheduled (Javadoc) アノテーションを使用して、5 秒ごとに現在の時刻を出力するアプリケーションを構築します。

必要なもの

このガイドを完了する方法

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了することも、このリポジトリ [GitHub] (英語) のコードを確認してソリューションに直接進むこともできます。

ローカル環境で最終結果を確認するには、次のいずれかを実行します。

Spring Initializr から開始

この事前に初期化されたプロジェクトを使用し、「生成」をクリックして ZIP ファイルをダウンロードできます。このプロジェクトは、このガイドの例に合わせて構成されています。

プロジェクトを手動で初期化するには:

  1. IDE のメニューまたはブラウザーから Spring Initializr を開きます。アプリケーションに必要なすべての依存関係を取り込み、ほとんどのセットアップを行います。

  2. Gradle または Maven と、使用する言語を選択します。このガイドでは、Java と Gradle を選択したことを前提としています。

  3. 生成をクリックします。

  4. 結果として得られる ZIP ファイルをダウンロードします。これは、選択した内容で構成されたアプリケーションのアーカイブです。

EclipseIntelliJ のような IDE は新規プロジェクト作成ウィザードから Spring Initializr の機能が使用できるため、手動での ZIP ファイルのダウンロードやインポートは不要です。

スケジューリングを有効にする

スケジュールされたタスクは Web アプリケーションに埋め込むことができますが、より簡単なメソッド (このガイドで説明) ではスタンドアロンアプリケーションを作成します。そのためには、すべてを 1 つの実行可能な JAR ファイルにパッケージ化し、Java main() メソッドで駆動します。次のスニペット (src/main/java/com/example/schedulingtasks/SchedulingTasksApplication.java から) は、アプリケーションクラスを示しています。

@SpringBootApplication
@EnableScheduling
public class SchedulingTasksApplication {

Spring Initializr は、メインクラスに @SpringBootApplication アノテーションを追加します。@SpringBootApplication は、次のすべてを追加する便利なアノテーションです。

  • @Configuration: アプリケーションコンテキストの Bean 定義のソースとしてクラスにタグを付けます。

  • @EnableAutoConfiguration: Spring Boot は、追加した依存関係に基づいて、Spring アプリケーションを自動的に構成しようとします。

  • @ComponentScan: Spring に他のコンポーネント、構成、サービスを検索するように指示します。特定のパッケージが定義されていない場合は、アノテーションを宣言するクラスのパッケージから再帰スキャンが開始されます。

さらに、@EnableScheduling アノテーションを追加します。このアノテーションにより、Spring のスケジュールされたタスク実行機能が有効になります。

スケジュールされたタスクを作成する

次のような新しいクラス src/main/java/com/example/schedulingtasks/ScheduledTasks.java を作成します。

@Component
public class ScheduledTasks {

	private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);

	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

	@Scheduled(fixedRate = 5000)
	public void reportCurrentTime() {
		log.info("The time is now {}", dateFormat.format(new Date()));
	}
}

Scheduled アノテーションは、特定のメソッドがいつ実行されるかを定義します。

この例では、各呼び出しの開始時刻から測定されたメソッド呼び出しの間隔を指定する fixedRate() (Javadoc) を使用します。他のオプションは cron() (Javadoc) fixedDelay() (Javadoc) です。定期的なタスクの場合は、これら 3 つのオプションのうち 1 つを指定する必要があります。オプションで initialDelay() (Javadoc) も指定できます。1 回限りのタスクの場合は、initialDelay() を指定するだけで十分です。

アプリケーションの実行

これで、SchedulingTasksApplication の main メソッドを実行してアプリケーションを実行できるようになります。プログラムは IDE から実行することも、プロジェクトルートディレクトリで次の Gradle コマンドを実行して実行することもできます。

./gradlew bootRun

こうするとアプリケーションが起動し、@Scheduled でアノテーションが付けられたメソッドが実行されます。次のようなログメッセージが表示されます。

20yy-mm-ddT07:23:01.665-04:00  INFO 19633 --- [   scheduling-1] c.e.schedulingtasks.ScheduledTasks       : The time is now 07:23:01
20yy-mm-ddT07:23:06.663-04:00  INFO 19633 --- [   scheduling-1] c.e.schedulingtasks.ScheduledTasks       : The time is now 07:23:06
20yy-mm-ddT07:23:11.663-04:00  INFO 19633 --- [   scheduling-1] c.e.schedulingtasks.ScheduledTasks       : The time is now 07:23:11
この例では fixedRate() (Javadoc) スケジューリングを使用しているため、手動で中断するまでアプリケーションは無期限に実行されます。

awaitility 依存関係を使用したテスト

アプリケーションを適切にテストするには、awaitility ライブラリ [GitHub] (英語) を使用できます。Spring Boot 3.2 以降、これは Boot が管理する依存関係です。src/test/java/com/example/schedulingtasks/ScheduledTasksTest.java で新しいテストを作成したり、既存のテストを表示したりできます。

@SpringBootTest
public class ScheduledTasksTest {

	@SpyBean
	ScheduledTasks tasks;

	@Test
	public void reportCurrentTime() {
		await().atMost(Durations.TEN_SECONDS).untilAsserted(() -> {
			verify(tasks, atLeast(2)).reportCurrentTime();
		});
	}
}

このテストは、./gradlew clean build タスクを実行すると自動的に実行されます。

アプリケーションの構築

このセクションでは、このガイドを実行するさまざまな方法について説明します。

アプリケーションの実行方法に関係なく、出力は同じになります。

アプリケーションを実行するには、アプリケーションを実行可能ファイル jar としてパッケージ化できます。./gradlew clean build コマンドは、アプリケーションを実行可能ファイル jar にコンパイルします。その後、java -jar build/libs/gs-scheduling-tasks-0.0.1-SNAPSHOT.jar コマンドを使用して jar を実行できます。

あるいは、Docker 環境が利用可能な場合は、buildpacks を使用して、Maven または Gradle プラグインから直接 Docker イメージを作成できます。Cloud Native Buildpacks を使用すると、どこでも実行できる Docker 互換イメージを作成できます。Spring Boot には、Maven と Gradle の両方に対する buildpack のサポートが直接含まれています。つまり、コマンドを 1 つ入力するだけで、ローカルで実行されている Docker デーモンに適切なイメージをすばやく取り込むことができます。Cloud Native Buildpacks を使用して Docker イメージを作成するには、./gradlew bootBuildImage コマンドを実行します。Docker 環境が有効になっている場合は、docker run docker.io/library/gs-scheduling-tasks:0.0.1-SNAPSHOT コマンドを使用してアプリケーションを実行できます。

ネイティブイメージのサポート

Spring Boot は、マシンに GraalVM ディストリビューションがインストールされている場合、ネイティブイメージへのコンパイルもサポートします。ネイティブビルドツールを使用して Gradle でネイティブイメージを作成するには、まず、Gradle ビルドに org.graalvm.buildtools.native を含む plugins ブロックが含まれていることを確認します。

plugins {
	id 'org.graalvm.buildtools.native' version '0.9.28'
...

次に、./gradlew nativeCompile コマンドを実行してネイティブイメージを生成します。ビルドが完了したら、build/native/nativeCompile/gs-scheduling-tasks コマンドを実行することで、ほぼ瞬時に起動してコードを実行できるようになります。

Buildpacks を使用したネイティブイメージを作成することもできます。./gradlew bootBuildImage コマンドを実行してネイティブイメージを生成できます。ビルドが完了したら、docker run docker.io/library/gs-scheduling-tasks:0.0.1-SNAPSHOT コマンドを使用してアプリケーションを起動できます。

要約

おめでとうございます。スケジュールされたタスクを含むアプリケーションを作成しました。

関連事項

次のガイドも役立ちます。

新しいガイドを作成したり、既存のガイドに貢献したいですか? 投稿ガイドラインを参照してください [GitHub] (英語)

すべてのガイドは、コード用の ASLv2 ライセンス、およびドキュメント用の Attribution、NoDerivatives creative commons ライセンス (英語) でリリースされています。

コードを入手する