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 作为数据源:
- 在
application.yml
中配置数据源 - 创建继承
DefaultTaskConfigurer
的类:
@Autowired
private DataSource dataSource;
public class HelloWorldTaskConfigurer extends DefaultTaskConfigurer{
public HelloWorldTaskConfigurer(DataSource dataSource){
super(dataSource);
}
}
- 注入配置的
DataSource
作为构造参数:
@Bean
public HelloWorldTaskConfigurer getTaskConfigurer() {
return new HelloWorldTaskConfigurer(dataSource);
}
✅ 完成配置后,TaskRepository
将持久化到 MySQL 数据库。
2.4. 实现
在 Spring Boot 中,可在应用启动完成前执行任务。使用 ApplicationRunner
或 CommandLineRunner
接口创建简单任务:
@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 生命周期
- 任务启动:在
TaskRepository
创建初始记录,表示所有 Bean 已就绪,Runner 接口的run
方法准备执行 - 任务结束:
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>
的负载,然后调用 Sink
的 input
通道发送消息。
6. 总结
本教程探讨了 Spring Cloud Task 的工作原理及其配置方法,包括:
✅ 将任务事件持久化到数据库
✅ 定义 Spring Batch 作业并存储到 TaskRepository
✅ 通过 Spring Cloud Stream 触发任务
完整代码可在 GitHub 获取。