Spring Boot使用@Schedule
排程(scheduling task)簡單範例如下。
本篇主要參考Spring官方教學Scheduling Tasks。
範例環境
- Java 8
- Maven
- IntelliJ IDEA
參考IntelliJ IDEA或Eclipse建立Spring Boot專案。
依賴設定參考範例的pom.xml
。
spring-boot-starter-web
中內含Spring的排程功能。
加入org.awaitility.awaitility
為測試非同步(asynchronous)程式的套件。
建立排程任務類別DemoScheduleTask
。類別加上@Component
使被掃描並註冊為Spring的Bean,在printUnixEpochTime()
前加上@Scheduled
則此方法則成為排程任務。@Scheduled
的屬性initialDelay=2000
表示排程開始後延遲2秒才執行;fixedRate = 3000
表示執行後每固定3秒再重複執行。
DemoScheduleTask
package com.abc.demo.schedule;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class DemoScheduleTask {
@Scheduled(initialDelay = 2000, fixedRate = 3000)
public void printUnixEpochTime() {
System.out.println(System.currentTimeMillis());
}
}
建立好任務必須在配置類@Configuration
加上@EnableScheduling
啟用排程則排程才會執行,範例是加在@SpringBootApplication
類,此注釋包含了@Configuration
。
DemoApplication
package com.abc.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling // <--- 啟用排程
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
執行後在console每3秒印出當前的unix epoch time。
1600399693180
1600399696177
1600399699174
1600399702171
使用awaitility
套件來撰寫測試程式DemoScheduleTaskTests
。
DemoScheduleTaskTests
package com.abc.demo.schedule;
import org.awaitility.Awaitility;
import org.awaitility.Durations;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
@SpringBootTest
class DemoScheduleTaskTests {
private final static int MIN_NUMBER_OF_INVOCATIONS = 2;
@SpyBean // 用@SpyBean才可被Mockito.verify驗證備測試對象的調用次數
DemoScheduleTask demoScheduleTask;
/**
* 測試DemoScheduleTask.printUnixEpochTime()在10秒鐘至少被執行2次
*/
@Test
void printUnixEpochTime_testInvocationAtLeastTwoTimesDuringTenSeconds() {
Awaitility.await()
.atMost(Durations.TEN_SECONDS) // 等待期間10秒
.untilAsserted( // 直到assert發生停止等待
() -> Mockito.verify(demoScheduleTask, Mockito.atLeast(MIN_NUMBER_OF_INVOCATIONS))
.printUnixEpochTime()); // 驗證demoScheduleTask.printUnixEpochTime()被調用2次
}
}
參考github。
沒有留言:
張貼留言