An Intro to Spring Cloud Task – Spring Cloud Task介绍

最后修改: 2018年 2月 27日

1. Overview


The goal of Spring Cloud Task is to provide the functionality of creating short-lived microservices for Spring Boot application.

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

In Spring Cloud Task, we’ve got the flexibility of running any task dynamically, allocating resources on demand and retrieving the results after the Task completion.

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

Tasks is a new primitive within Spring Cloud Data Flow allowing users to execute virtually any Spring Boot application as a short-lived task.

任务是Spring Cloud Data Flow中的一个新基元,允许用户将几乎任何Spring Boot应用程序作为一个短暂的任务执行

2. Developing a Simple Task Application


2.1. Adding Relevant Dependencies


To start, we can add dependency management section with spring-cloud-task-dependencies:



This dependency management manages versions of dependencies through the import scope.


We need to add the following dependencies:



This is the link to the Maven Central of spring-cloud-task-core.

这个是指向 spring-cloud-task-core的Maven中心的链接。

Now, to start our Spring Boot application, we need spring-boot-starter with the relevant parent.

现在,为了启动我们的Spring Boot应用程序,我们需要spring-boot-starter与相关的父级。

We’re going to use Spring Data JPA as an ORM tool, so we need to add the dependency for that as well:

我们将使用Spring Data JPA作为ORM工具,所以我们也需要添加它的依赖性。


The details of bootstrapping a simple Spring Boot application with Spring Data JPA are available here.

使用 Spring Data JPA 引导一个简单的 Spring Boot 应用程序的细节可在此处获得。

We can check the newest version of the spring-boot-starter-parent on Maven Central.

我们可以查看spring-boot-starter-parentn Maven Central的最新版本。

2.2. The @EnableTask Annotation

2.2.@EnableTask 注释

To bootstrap the functionality of Spring Cloud Task, we need to add @EnableTask annotation:

为了启动Spring Cloud Task的功能,我们需要添加@EnableTask注释。

public class TaskDemo {
    // ...

The annotation brings SimpleTaskConfiguration class in the picture which in turns registers the TaskRepository and its infrastructure. By default, an in-memory map is used to store the status of the TaskRepository.


The primary information of TaskRepository is modeled in TaskExecution class. The noted fields of this class are taskName, startTime, endTime, exitMessage. The exitMessage stores the available information at the exit time.


If an exit is caused by a failure in any event of the application, the complete exception stack trace will be stored here.


Spring Boot provides an interface ExitCodeExceptionMapper which maps uncaught exceptions to exit codes allowing scrutinized debug. The Cloud Task stores the information in the data source for future analysis.

Spring Boot提供了一个接口ExitCodeExceptionMapper,它将未捕获的异常映射为退出代码,允许仔细调试。云任务将信息存储在数据源中,以便将来分析。

2.3. Configuring a DataSource for TaskRepository


The in-memory map to store the TaskRepository will vanish once the task ends and we’ll lose data related to Task events. To store in a permanent storage, we’re going to use MySQL as a data source with Spring Data JPA.

一旦任务结束,用于存储TaskRepository的内存地图将消失,我们将失去与任务事件相关的数据。为了存储在一个永久的存储器中,我们将使用MySQL作为数据源与Spring Data JPA。

The data source is configured in application.yml file. To configure Spring Cloud Task to use the provided data source as an storage of TaskRepository, we need to create a class that extends DefaultTaskConfigurer.

数据源是在application.yml文件中配置的。为了配置Spring Cloud Task使用所提供的数据源作为TaskRepository的存储,我们需要创建一个扩展DefaultTaskConfigurer的类。

Now, we can send configured Datasource as a constructor argument to the superclass’ constructor:


private DataSource dataSource;

public class HelloWorldTaskConfigurer extends DefaultTaskConfigurer{
    public HelloWorldTaskConfigurer(DataSource dataSource){

To have the above configuration in action, we need to annotate an instance of DataSource with @Autowired annotation and inject the instance as constructor-argument of a HelloWorldTaskConfigurer bean defined above:


public HelloWorldTaskConfigurer getTaskConfigurer() {
    return new HelloWorldTaskConfigurer(dataSource);

This completes the configuration to store TaskRepository to MySQL database.


2.4. Implementation


In Spring Boot, we can execute any Task just before application finishes its startup. We can use ApplicationRunner or CommandLineRunner interfaces to create a simple Task.

在Spring Boot中,我们可以在应用程序完成启动之前执行任何任务。我们可以使用ApplicationRunnerCommandLineRunner接口来创建一个简单的任务。

We need to implement the run method of these interfaces and declare the implementing class as a bean:


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

Now, if we run our application, we should get our task producing necessary output with required tables created in our MySQL database logging the event data of the Task.


3. Life-cycle of a Spring Cloud Task

3.Spring Cloud任务的生命周期

In the beginning, we create an entry in the TaskRepository. This’s the indication that all beans are ready to be used in the Application and the run method of Runner interface is ready to be executed.


Upon completion of the execution of the run method or in any failure of ApplicationContext event, TaskRepository will be updated with another entry.


During the task life-cycle, we can register listeners available from TaskExecutionListener interface. We need a class implementing the interface having three methods – onTaskEnd, onTaksFailed and onTaskStartup triggered in respective events of the Task.


We need to declare the bean of the implementing class in our TaskDemo class:


public TaskListener taskListener() {
    return new TaskListener();

4. Integration With Spring Batch

4.与Spring Batch的集成

We can execute Spring Batch Job as a Task and log events of the Job execution using Spring Cloud Task. To enable this feature we need to add Batch dependencies pertaining to Boot and Cloud:

我们可以将Spring Batch Job作为一个任务来执行,并使用Spring Cloud Task来记录Job执行的事件。要启用这个功能,我们需要添加与Boot和Cloud有关的Batch依赖。


Here is the link to the Maven Central of spring-cloud-task-batch.


To configure a job as a Task we need to have the Job bean registered in the JobConfiguration class:

要将一项工作配置为一个任务,我们需要在JobConfiguration类中注册Job Bean。

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

We need to decorate the TaskDemo class with @EnableBatchProcessing annotation:


//..Other Annotation..
public class TaskDemo {
    // ...

The @EnableBatchProcessing annotation enables Spring Batch features with a base configuration required to set up batch jobs.

@EnableBatchProcessing注解通过设置批处理工作所需的基本配置来启用Spring Batch功能。

Now, if we run the application, the @EnableBatchProcessing annotation will trigger the Spring Batch Job execution and Spring Cloud Task will log the events of the executions of all batch jobs with the other Task executed in the springcloud database.


5. Launching a Task from Stream


We can trigger Tasks from Spring Cloud Stream. To serve this purpose, we have the @EnableTaskLaucnher annotation. Once, we add the annotation with Spring Boot app, a TaskSink will be available:

我们可以从Spring Cloud Stream触发任务。为了达到这个目的,我们有@EnableTaskLaucnher注解。一旦我们在Spring Boot应用程序中添加该注解,就会有一个TaskSink可用。

public class StreamTaskSinkApplication {
    public static void main(String[] args) {, args);

The TaskSink receives the message from a stream that contains a GenericMessage containing TaskLaunchRequest as a payload. Then it triggers a Task-based on co-ordinate provided in the Task launch request.


To have TaskSink functional, we require a bean configured that implements TaskLauncher interface. For testing purpose, we’re mocking the implementation here:


public TaskLauncher taskLauncher() {
    return mock(TaskLauncher.class);

We need to note here that the TaskLauncher interface is only available after adding the spring-cloud-deployer-local dependency:



We can test whether the Task launched by invoking input of the Sink interface:


public class StreamTaskSinkApplicationTests {
    private Sink sink; 

Now, we create an instance of TaskLaunchRequest and send that as a payload of GenericMessage<TaskLaunchRequest> object. Then we can invoke the input channel of the Sink keeping the GenericMessage object in the channel.

现在,我们创建一个TaskLaunchRequest的实例,并将其作为GenericMessage<TaskLaunchRequest> 对象的有效载荷发送。然后我们可以调用Sinkinput通道,将GenericMessage对象保留在该通道中。

6. Conclusion


In this tutorial, we’ve explored how Spring Cloud Task performs and how to configure it to log its events in a database. We also observed how Spring Batch job is defined and stored in the TaskRepository. Lastly, we explained how we can trigger Task from within Spring Cloud Stream.

在本教程中,我们已经探讨了Spring Cloud Task是如何执行的,以及如何配置它在数据库中记录其事件。我们还观察了Spring Batch作业是如何定义并存储在TaskRepository中的。最后,我们解释了如何从Spring Cloud Stream中触发任务。

As always, the code is available over on GitHub.