Spring Bootで@Scheduledアノテーションを使おう


皆さんはSpring Bootで定期的に実行したい処理、例えばログローテーションやデータのバックアップなど、ありますでしょうか?
そんな時に使えるのが、@Scheduledアノテーションです。Springには、Spring Batchのようなバッチ処理フレームワークもありますが、簡単な定期実行処理には@Scheduledアノテーションが便利です。
この記事では、@Scheduledアノテーションの使い方を、具体的なコード例を交えながら解説します。

@Scheduledアノテーションとは?

@ScheduledアノテーションはSpring Frameworkが提供する機能で、指定したスケジュールに従ってメソッドを実行してくれます。特に追加でライブラリなどの導入は不要なので、気軽に利用できます。
必要なのは、@EnableSchedulingアノテーションを有効にしたクラスを定義することだけです。
これは、Spring Bootがスケジュールされたタスクを検出して管理するために必要になります。

使い方

例えば、以下のようなクラスを考えましょう。

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@EnableScheduling
public class ScheduledTask {

    @Scheduled(fixedRate = 5000) // 5秒ごとに実行
    public void reportCurrentTime() {
        System.out.println("現在時刻: " + LocalDateTime.now());
    }

    @Scheduled(cron = "0 0 * * * *") // 毎時0分に実行
    public void executeEveryHour() {
        System.out.println("毎時0分に実行されるタスクです。");
    }
}

このコードでは、@ComponentアノテーションによってSpringコンテナに管理されるScheduledTaskクラスを定義しています。
@EnableSchedulingアノテーションにより、スケジュールされたタスクの機能が有効になります。

reportCurrentTime()メソッドは、@Scheduled(fixedRate = 5000)によって5秒ごとに実行されます。fixedRate属性は、前回のメソッド実行開始から次の実行開始までの時間をミリ秒単位で指定します。

executeEveryHour()メソッドは、@Scheduled(cron = "0 0 * * * *")によって1分ごとに実行されます。cron属性はcron式を使用し、より柔軟なスケジュール設定が可能です。 cron式は、秒、分、時、日、月、曜日の順で指定します。 "0 0 * * * *" は、「毎時0分0秒に実行する」という意味になります。
cron式の詳細な書き方については、詳細をまとめた記事や便利なツールがあったりするので、調べてみると良いでしょう。

その他の属性

上記で触れた以外にも、@ScheduledアノテーションにはfixedDelayinitialDelayなどの属性があり、これらを使うことで、より詳細なスケジュール設定を行うことができます。fixedDelayは、前回のメソッド実行完了から次の実行開始までの時間をミリ秒単位で指定しますが、fixedRateと異なり、メソッドの実行時間が考慮されます。initialDelayは、最初のメソッド実行までの遅延時間をミリ秒単位で指定します。

また、タイムゾーンを指定するzone属性もあります。デフォルトでは、システムのデフォルトタイムゾーンが使用されますが、必要に応じて指定することができます。 確実に日本時間で動かしたい、といった場合には以下のように指定しておくと良いでしょう。

@Scheduled(cron = "0 0 * * * *", zone = "Asia/Tokyo")

まとめ

@Scheduledアノテーションは、定期的なタスクの実行を簡潔に記述できる強力なツールです。cron式をマスターすれば、様々なスケジュールに対応できるようになります。
ぜひ、自分のアプリケーションで活用してみてください。
そして、必要に応じてエラー処理やログ出力なども追加し、堅牢なシステム構築を目指しましょう。