0
1

More than 1 year has passed since last update.

Springの @Scheduled について

Last updated at Posted at 2022-10-23

概要

Springが提供している @Scheduledについて調べたので、そのメモを残す。

下記のversionで検証を行った。

  • Java17(Corretto 17.0.5)
  • SpringBoot2.7.5

検証コードは下記に格納している。
https://github.com/nannany/spring-scheduled

@Scheduledとは?

@Scheduledアノテーションをメソッドに付与することで、メソッドの定期的な実行を行うことができる。
例えば、下記のようなメソッドはfixedRate_withTimeUnitという文言を1分ごとに標準出力する。

    @Scheduled(fixedRate = 1, timeUnit = TimeUnit.MINUTES)
    public void fixedRate_withTimeUnit() {
        logger.info("fixedRate_withTimeUnit");
    }

@Scheduledを有効にするには?

@Scheduledを有効にするには、下記のように@Configurationが付与されたクラスに、@EnableSchedulingを付与してやれば良い。(参考)

@Configuration
@EnableScheduling
@ComponentScan(basePackages = "com.example.demo.tasks")
public class EnableSchedulingConfig implements SchedulingConfigurer {
  ...

@Scheduledの機能

@Scheduledでメソッドの定期的な実行を行うことができるが、実行タイミングの指定方法は複数ある。

fixedRate

fixRateを用いた指定方法では、シンプルな定期実行が可能である。
下記のメソッドのように指定した場合、5秒ごとに fixedRateという文言がログに吐き出される。

    @Scheduled(fixedRate = 5000)
    public void fixedRate() throws InterruptedException {
        Thread.sleep(1000);
        logger.info("fixedRate");
    }

fixedRateで指定する値はデフォルトでミリ秒であるが、timeUnitによって指定することが可能である。

    @Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS)
    public void fixedRate_withTimeUnit() {
        logger.info("fixedRate_withTimeUnit");
    }

fixedDelay

fixedDelayでは、該当のメソッドが終了してから指定した時間経った後に再度メソッドが実行される。
例えば、下記の場合だと6秒ごとに fixedDelayという文言が出力される。
途中でsleepしているため、メソッドの実行には1秒かかり、その完了の後の5秒後にメソッドが再度実行されるため、6秒ごとのログ出力となる。

    @Scheduled(fixedDelay = 5000)
    public void fixedDelay() throws InterruptedException {
        Thread.sleep(1000);
        logger.info("fixedDelay");
    }

cron

cronではいわゆるcron式による定義が可能となる。
下記の例だと、5秒ごとに cron をログ出力する。ちなみにタイムゾーンの指定も可能である。(下記の例だと意味をなしていないが)

    @Scheduled(cron = "*/5 * * * * *", zone = "Asia/Tokyo")
    public void cron() {
        logger.info("cron");
    }

ランタイムで次回実行を決めたいとき

@Scheduledではアプリケーションコンテキスト生成時に実行間隔が決定するため、ランタイム時に次回実行を決定したい時には ScheduledTaskRegistrar をいじってやる必要がある。

下記の例だと、 cumstom schedulerという文言が 1~5秒ごとにログ出力されるようになる。

    @Bean
    public Executor taskExecutor() {
        return Executors.newSingleThreadScheduledExecutor();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());

        taskRegistrar.addTriggerTask(
                () -> logger.info("custom scheduler"),
                triggerContext -> {
                    Random random = new Random();
                    Date date = new Date();
                    return Date.from(date.toInstant().plusSeconds(random.nextInt(5) + 1));
                }
        );

    }

参考

https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling
https://www.baeldung.com/spring-scheduled-tasks

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1