入门指南

如果您刚开始使用 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

  • PostgreSQL

  • SQL Server

开发您的第一个 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 项目,其**组**名称为io.spring.demo,**构件**名称为helloworld

    2. 在“依赖项”文本框中,键入task,然后选择带有Spring Cloud标签的Task依赖项。

    3. 在“依赖项”文本框中,键入h2,然后选择带有SQL标签的H2依赖项。

    4. 单击**生成项目**按钮。

  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

Task 自动配置

包含 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#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!”输出演示。

  • SimpleTaskRepository记录了在TaskRepository中完成任务的日志。

可以在 Spring Cloud Task 项目的示例模块中找到一个简单的任务应用程序此处