アプリケーションにCRON
を使用してセットアップされた@Scheduled
タスクがあり、4時間ごとに実行されます。私が直面している問題は、CRON
ジョブがアプリケーションの起動直後に開始されないが、アプリケーションの起動後4時間で開始されることです。
タスク内で@PostConstruct
メソッドを使用してそれを呼び出そうとしましたが、初期化されていないSpringコンテキストが原因でエラーが発生します。
スケジュールされたタスクをアプリケーションの展開直後に実行し、展開後4時間ごとに実行する方法を教えてください。
編集:
スケジュールされたメソッドは他のBeanに依存しているため、@PostConstruct
は使用しません。他のBeanは、このPostConstructメソッドが何らかの理由で実行されたときに初期化されません。
0までに*/4 * * *「4時間ごと(0:00、4:00、8:00など)の0分に」を指定します。これは起動時ではなく、4時間ごとです。欲しいです。初期遅延とレートは次の方法で指定できます。
@Scheduled(initialDelay=0, fixedRate=4*60*60*1000)
ハードコードされた値が心配な場合でも、構成値を指定できます。
@Scheduled(initialDelay=0, fixedRateString = "${some.config.string}")
アプリの構成に_@EnableScheduling
_がありました。スケジュールされたタスククラスに@Scheduled(fixedDelay=5000)
がありました。それでもうまくいきませんでした。
スケジュールされたタスククラスに_@Service
_を追加しましたが、すべて正常に機能しました。
これを試したかどうかはわかりませんが、@Scheduled
をinitialDelay
と一緒に使用できます
固定遅延および固定レートのタスクの場合、メソッドのfirst実行まで待機するミリ秒数を示す初期遅延を指定できます。
@Scheduled(initialDelay=0, fixedRate=5000)
public void doSomething() {
// something that should execute periodically
}
これにより、アプリケーションの実行時にスケジュールされたメソッドが実行されると思います。
initialDelay
ルールでcron
属性を使用できず、再起動するたびにこのジョブを実行することが意図されている場合は、アプリケーションクラスにCommandLineRunner
を実装できます。
@SpringBootApplication
public class MyApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Autowired
private TaskService taskService;
@Override
public void run(final String... args) throws Exception {
taskService.run();
}
}
これは最善の戦略ではありませんが、機能します。
Beanの_init_method
_属性で実行するメソッドを指定するだけです。
Java構成:@Bean(init_method="methodWhichStartsTask")
XML構成:_<bean id="someId" class="com.example.Clazz" init-method="methodWhichStartsTask"/>
_
これにより、Beanが適切に初期化された直後にメソッドが呼び出され、メソッドがスケジュールされている場合は、その後4時間ごとに呼び出されます。
@Scheduled内のcronの代わりに、以下のようにfixedRateを使用します。デフォルトでは、initialDelayは-1で、すぐに開始するか、0に設定できます。
@Scheduled(fixedRate=4*60*60*1000)
public void test() {
System.out.println("helloworld");
}
私も同じ状況でした。月の1日ごとに、またアプリケーションの起動時にcronスケジューラを実行する必要があります。
これは私がApplicationListenerを使用して達成した方法です。
import org.springframework.context.ApplicationListener;
import org.springframework.boot.context.event.ApplicationReadyEvent;
@Component
public class ApplicationReadyListner implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
// callYourTask();
}
}