Spring Cron の形式
Spring の式は秒・分・時・日・月・曜日の 6 フィールドです。たとえば 0 0 9 * * MON-FRI は平日の 09:00 を表します。日曜日は 0、7、SUN のいずれでも書けます。Spring Framework 5.3 以降は、日付フィールドの L・W・# や、@hourly・@daily などのマクロも解釈できます。
@Scheduled のタイムゾーン
デフォルトでは、式はサーバーのデフォルトタイムゾーンで評価されます。@Scheduled(cron = "0 0 2 * * *", zone = "Asia/Tokyo") のように zone 属性を設定すると、ホストに依存しないスケジュールになります。ツールで同じタイムゾーンを選んで実行時刻を確認しましょう。
Spring と Quartz の違い
Spring の式は Quartz とよく似ていますが、細部が異なります。年フィールドがなく、日曜日は 1 ではなく 0、そして「?」は使えますが必須ではありません。日と曜日の両方を指定した場合、Spring では両方の一致が必要です。等価な式があれば、変換ツールが Quartz 版を表示します。
スケジューリングの有効化
cron メソッドは @EnableScheduling でスケジューリングを有効にしたときだけ実行されます。Spring はデフォルトでスレッドを 1 つしか使わないため、長いタスクがほかのすべての定期メソッドを遅らせます。複数のジョブがある場合は ThreadPoolTaskScheduler か spring.task.scheduling.pool.size を設定しましょう。クラスタではすべてのインスタンスが同じ cron で起動するので、1 回だけ実行したいジョブには ShedLock などのロックを使います。
よくある質問
- Spring で Cron 式は 6 フィールド必要と言われるのはなぜ?
- Spring には秒フィールドが必要だからです。5 フィールドの crontab 式の先頭に 0 を付けます。0 */5 * * * * は 5 分ごとに実行されます。
- @Scheduled の Cron ジョブを無効にするには?
- 特別な値 "-"(Scheduled.CRON_DISABLED)を使います。通常はプロパティのプレースホルダー経由で設定します。
- Spring は月末日に対応していますか?
- はい、5.3 以降は対応しています。0 0 0 L * * は毎月最終日の午前 0 時に実行されます。
- Cron 式を設定ファイルから読み込めますか?
- はい。@Scheduled(cron = "${jobs.cleanup.cron}") のようにすれば、環境ごとにスケジュールを変えられます。