1. 概述

Spring Cloud Task 的核心目标是为 Spring Boot 应用提供创建短期微服务的功能

在 Spring Cloud Task 中,我们可以动态运行任何任务,按需分配资源,并在任务完成后获取结果。

任务是 Spring Cloud Data Flow 中的一种新原语,允许用户将几乎任何 Spring Boot 应用作为短期任务执行

2. 开发简单任务应用

2.1. 添加相关依赖

首先,我们添加依赖管理部分 spring-cloud-task-dependencies

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-task-dependencies</artifactId>
            <version>2.2.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

此依赖管理通过 import scope 统一管理依赖版本

需要添加以下核心依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-task</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-task-core</artifactId>
</dependency>

点击这里查看 spring-cloud-task-core 的 Maven 中央仓库信息。

启动 Spring Boot 应用需要 spring-boot-starter 和相关父级依赖。我们使用 Spring Data JPA 作为 ORM 工具,因此添加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.6.1</version>
</dependency>

Maven Central 可查看 spring-boot-starter-parent 最新版本。

2.2. @EnableTask 注解

启用 Spring Cloud Task 功能需添加 @EnableTask 注解:

@SpringBootApplication
@EnableTask
public class TaskDemo {
    // ...
}

该注解引入 SimpleTaskConfiguration 类,进而注册 TaskRepository 及其基础设施。默认使用内存映射存储 TaskRepository 状态。

TaskRepository 的核心信息由 TaskExecution 类建模,关键字段包括:

  • taskName:任务名称
  • startTime:开始时间
  • endTime:结束时间
  • exitMessage:退出信息(存储退出时的可用信息)

若因应用事件失败退出,此处会存储完整异常堆栈。

Spring Boot 提供 ExitCodeExceptionMapper 接口,将未捕获异常映射为退出码便于调试。Cloud Task 将信息持久化到数据源供后续分析。

2.3. 配置 TaskRepository 的数据源

内存映射存储 TaskRepository 会在任务结束时丢失数据。为永久存储,我们使用 MySQL 作为数据源:

  1. application.yml 中配置数据源
  2. 创建继承 DefaultTaskConfigurer 的类:
@Autowired
private DataSource dataSource;

public class HelloWorldTaskConfigurer extends DefaultTaskConfigurer{
    public HelloWorldTaskConfigurer(DataSource dataSource){
        super(dataSource);
    }
}
  1. 注入配置的 DataSource 作为构造参数:
@Bean
public HelloWorldTaskConfigurer getTaskConfigurer() {
    return new HelloWorldTaskConfigurer(dataSource);
}

✅ 完成配置后,TaskRepository 将持久化到 MySQL 数据库。

2.4. 实现

在 Spring Boot 中,可在应用启动完成前执行任务。使用 ApplicationRunnerCommandLineRunner 接口创建简单任务:

@Component
public static class HelloWorldApplicationRunner 
  implements ApplicationRunner {
 
    @Override
    public void run(ApplicationArguments arg0) throws Exception {
        System.out.println("Hello World from Spring Cloud Task!");
    }
}

运行应用后,任务将输出结果,并在 MySQL 数据库中创建相应表记录任务事件。

3. Spring Cloud Task 生命周期

  1. 任务启动:在 TaskRepository 创建初始记录,表示所有 Bean 已就绪,Runner 接口的 run 方法准备执行
  2. 任务结束run 方法执行完成或 ApplicationContext 失败时,更新 TaskRepository 记录

在任务生命周期中,可通过 TaskExecutionListener 接口注册监听器。实现类需定义三个方法:

  • onTaskEnd:任务结束时触发
  • onTaskFailed:任务失败时触发
  • onTaskStartup:任务启动时触发

TaskDemo 类中声明监听器 Bean:

@Bean
public TaskListener taskListener() {
    return new TaskListener();
}

4. 与 Spring Batch 集成

可将 Spring Batch 作业作为任务执行,并通过 Spring Cloud Task 记录执行事件。添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-task-batch</artifactId>
</dependency>

点击这里查看 spring-cloud-task-batch 的 Maven 中央仓库信息。

JobConfiguration 类中注册作业 Bean:

@Bean
public Job job2() {
    return jobBuilderFactory.get("job2")
      .start(stepBuilderFactory.get("job2step1")
      .tasklet(new Tasklet(){
          @Override
          public RepeatStatus execute(
            StepContribution contribution,
            ChunkContext chunkContext) throws Exception {
            System.out.println("This job is from Baeldung");
                return RepeatStatus.FINISHED;
          }
    }).build()).build();
}

需在 TaskDemo 类添加 @EnableBatchProcessing 注解

//其他注解...
@EnableBatchProcessing
public class TaskDemo {
    // ...
}

@EnableBatchProcessing 注解启用 Spring Batch 功能,提供设置批处理作业的基础配置

运行应用后,@EnableBatchProcessing 将触发 Spring Batch 作业执行,Spring Cloud Task 会在数据库中记录所有批处理作业事件。

5. 从流中启动任务

可通过 Spring Cloud Stream 触发任务。使用 @EnableTaskLauncher 注解:

@SpringBootApplication
@EnableTaskLauncher
public class StreamTaskSinkApplication {
    public static void main(String[] args) {
        SpringApplication.run(TaskSinkApplication.class, args);
    }
}

TaskSink 接收流中包含 TaskLaunchRequest 的消息,并基于请求中的坐标触发任务。

要使 TaskSink 生效,需配置实现 TaskLauncher 接口的 Bean(测试用模拟实现):

@Bean
public TaskLauncher taskLauncher() {
    return mock(TaskLauncher.class);
}

⚠️ 注意TaskLauncher 接口仅在添加 spring-cloud-deployer-local 依赖后可用:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-deployer-local</artifactId>
    <version>2.3.1.RELEASE</version>
</dependency>

通过调用 Sink 接口的 input 测试任务启动:

public class StreamTaskSinkApplicationTests {
   
    @Autowired
    private Sink sink; 
    
    //
}

创建 TaskLaunchRequest 实例作为 GenericMessage<TaskLaunchRequest> 的负载,然后调用 Sinkinput 通道发送消息。

6. 总结

本教程探讨了 Spring Cloud Task 的工作原理及其配置方法,包括: ✅ 将任务事件持久化到数据库 ✅ 定义 Spring Batch 作业并存储到 TaskRepository ✅ 通过 Spring Cloud Stream 触发任务

完整代码可在 GitHub 获取。


原始标题:An Intro to Spring Cloud Task