入門

如果您剛開始接觸 Spring Cloud Task,應該閱讀本節。在這裡,我們將回答基本的“是什麼?”、“如何做?”和“為什麼?”問題。我們將從對 Spring Cloud Task 的溫和介紹開始。然後,我們將構建一個 Spring Cloud Task 應用,同時討論一些核心原則。

介紹 Spring Cloud Task

Spring Cloud Task 使建立短生命週期的微服務變得容易。它提供了能夠在生產環境中按需執行短生命週期 JVM 程序的功能。

系統要求

您需要安裝 Java (Java 17 或更高版本)。

資料庫要求

Spring Cloud Task 使用關係型資料庫儲存執行任務的結果。雖然您可以在沒有資料庫的情況下開始開發任務(任務狀態會作為任務倉庫更新的一部分進行日誌記錄),但在生產環境中,您需要使用受支援的資料庫。Spring Cloud Task 當前支援以下資料庫

  • DB2

  • H2

  • HSQLDB

  • MySql

  • Oracle

  • Postgres

  • SqlServer

開發您的第一個 Spring Cloud Task 應用

一個好的開始是編寫一個簡單的“Hello, World!” 應用,因此我們建立一個等同的 Spring Cloud Task 應用來突出框架的特性。大多數 IDE 都很好地支援 Apache Maven,所以我們將其用作此專案的構建工具。

spring.io 網站包含許多使用 Spring Boot 的入門”指南。如果您需要解決特定問題,請先在那裡查詢。您可以透過訪問 Spring Initializr 並建立一個新專案來縮短以下步驟。這樣做會自動生成一個新的專案結構,以便您可以立即開始編碼。我們建議您透過 Spring Initializr 進行實驗,以熟悉它。

使用 Spring Initializr 建立 Spring Task 專案

現在我們可以建立並測試一個將 Hello, World! 列印到控制檯的應用。

為此

  1. 訪問 Spring Initializr 網站。

    1. 建立一個新的 Maven 專案,Group 名稱為 io.spring.demoArtifact 名稱為 helloworld

    2. 在 Dependencies 文字框中,輸入 task,然後選擇帶有 Spring Cloud 標籤的 Task 依賴。

    3. 在 Dependencies 文字框中,輸入 h2,然後選擇帶有 SQL 標籤的 H2 依賴。

    4. 點選 Generate Project 按鈕

  2. 解壓 helloworld.zip 檔案並將專案匯入您喜歡的 IDE。

編寫程式碼

為了完成我們的應用,我們需要使用以下內容更新生成的 HelloworldApplication,以便它能夠啟動一個 Task。

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableTask
public class HelloworldApplication {

	@Bean
	public ApplicationRunner applicationRunner() {
		return new HelloWorldApplicationRunner();
	}

	public static void main(String[] args) {
		SpringApplication.run(HelloworldApplication.class, args);
	}

	public static class HelloWorldApplicationRunner implements ApplicationRunner {

		@Override
		public void run(ApplicationArguments args) throws Exception {
			System.out.println("Hello, World!");

		}
	}
}

儘管看起來很小,但實際上有很多事情正在發生。有關 Spring Boot 的更多細節,請參閱 Spring Boot 參考文件

現在我們可以開啟 src/main/resources 目錄下的 application.properties 檔案。我們需要在 application.properties 中配置兩個屬性:

  • application.name: 用於設定應用名稱(這將轉換為任務名稱)

  • logging.level: 將 Spring Cloud Task 的日誌級別設定為 DEBUG,以便了解正在發生的事情。

以下示例展示瞭如何進行配置

logging.level.org.springframework.cloud.task=DEBUG
spring.application.name=helloWorld

任務自動配置

當引入 Spring Cloud Task Starter 依賴時,Task 會自動配置所有 bean 來啟動其功能。此配置的一部分是註冊 TaskRepository 及其使用基礎設施。

在我們的演示中,TaskRepository 使用嵌入式 H2 資料庫記錄任務結果。由於 H2 資料庫在任務結束時就會消失,因此這種嵌入式 H2 資料庫對於生產環境來說不是一個實用的解決方案。然而,對於快速入門體驗,我們可以在示例中使用它,並將倉庫中更新的內容回顯到日誌中。在本文件後面的配置部分,我們將介紹如何自定義 Spring Cloud Task 提供的元件配置。

當我們的示例應用執行時,Spring Boot 會啟動我們的 HelloWorldApplicationRunner 並將“Hello, World!” 訊息輸出到標準輸出。TaskLifecycleListener 會在倉庫中記錄任務的開始和結束。

main 方法

main 方法是任何 Java 應用的入口點。我們的 main 方法委託給 Spring Boot 的 SpringApplication 類。

ApplicationRunner

Spring 包含許多啟動應用邏輯的方法。Spring Boot 透過其 *Runner 介面 (CommandLineRunnerApplicationRunner) 提供了一種有序且便捷的方式。一個良好的任務可以透過使用這兩個 runner 之一來啟動任何邏輯。

任務的生命週期從 *Runner#run 方法執行之前開始,到所有方法執行完成為止。Spring Boot 允許一個應用使用多個 *Runner 實現,Spring Cloud Task 也是如此。

透過 CommandLineRunnerApplicationRunner 之外的機制(例如使用 InitializingBean#afterPropertiesSet)啟動的任何處理都不會被 Spring Cloud Task 記錄。

執行示例

至此,我們的應用應該可以工作了。由於此應用基於 Spring Boot,我們可以從應用的根目錄使用命令列 $ ./mvnw spring-boot:run 執行它,如下例所示(包含其輸出)

$ mvn clean spring-boot:run
....... . . .
....... . . . (Maven log output here)
....... . . .

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.1)

2024-01-04T10:07:01.102-06:00  INFO 18248 --- [helloWorld] [           main] i.s.d.helloworld.HelloworldApplication   : Starting HelloworldApplication using Java 21.0.1 with PID 18248 (/Users/dashaun/fun/dashaun/spring-cloud-task/helloworld/target/classes started by dashaun in /Users/dashaun/fun/dashaun/spring-cloud-task/helloworld)
2024-01-04T10:07:01.103-06:00  INFO 18248 --- [helloWorld] [           main] i.s.d.helloworld.HelloworldApplication   : No active profile set, falling back to 1 default profile: "default"
2024-01-04T10:07:01.526-06:00  INFO 18248 --- [helloWorld] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2024-01-04T10:07:01.626-06:00  INFO 18248 --- [helloWorld] [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:3ad913f8-59ce-4785-bf8e-d6335dff6856 user=SA
2024-01-04T10:07:01.627-06:00  INFO 18248 --- [helloWorld] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2024-01-04T10:07:01.633-06:00 DEBUG 18248 --- [helloWorld] [           main] o.s.c.t.c.SimpleTaskAutoConfiguration    : Using org.springframework.cloud.task.configuration.DefaultTaskConfigurer TaskConfigurer
2024-01-04T10:07:01.633-06:00 DEBUG 18248 --- [helloWorld] [           main] o.s.c.t.c.DefaultTaskConfigurer          : No EntityManager was found, using DataSourceTransactionManager
2024-01-04T10:07:01.639-06:00 DEBUG 18248 --- [helloWorld] [           main] o.s.c.t.r.s.TaskRepositoryInitializer    : Initializing task schema for h2 database
2024-01-04T10:07:01.772-06:00 DEBUG 18248 --- [helloWorld] [           main] o.s.c.t.r.support.SimpleTaskRepository   : Creating: TaskExecution{executionId=0, parentExecutionId=null, exitCode=null, taskName='helloWorld', startTime=2024-01-04T10:07:01.757268, endTime=null, exitMessage='null', externalExecutionId='null', errorMessage='null', arguments=[]}
2024-01-04T10:07:01.785-06:00  INFO 18248 --- [helloWorld] [           main] i.s.d.helloworld.HelloworldApplication   : Started HelloworldApplication in 0.853 seconds (process running for 1.029)
Hello, World!
2024-01-04T10:07:01.794-06:00 DEBUG 18248 --- [helloWorld] [           main] o.s.c.t.r.support.SimpleTaskRepository   : Updating: TaskExecution with executionId=1 with the following {exitCode=0, endTime=2024-01-04T10:07:01.787112, exitMessage='null', errorMessage='null'}
2024-01-04T10:07:01.799-06:00  INFO 18248 --- [helloWorld] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2024-01-04T10:07:01.806-06:00  INFO 18248 --- [helloWorld] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

....... . . .
....... . . . (Maven log output here)
....... . . .

前面的輸出中有三行是我們感興趣的:

  • SimpleTaskRepository 記錄了在 TaskRepository 中建立的條目。

  • 我們的 ApplicationRunner 的執行,由“Hello, World!” 輸出證明。

  • SimpleTaskRepositoryTaskRepository 中記錄了任務的完成。

一個簡單的任務應用可以在 Spring Cloud Task 專案的 samples 模組中找到,請點選這裡