当前位置: 首页 > 知识库问答 >
问题:

如何在运行时创建和启动spring批处理作业

松思源
2023-03-14

我们需要执行从一个数据库到其他数据库的数据移动,并为此探索spring batch。我们应用程序的用户选择源数据源和目标数据源,以及需要为其移动数据的表列表。

在以下方面需要帮助:

  1. 构建作业所需的信息在运行时来自我们的web应用程序-包括数据源详细信息和表名列表。我们希望通过将这些详细信息发送到job builder模块来创建一个新作业,并使用JobLauncher启动它。我们如何编写这个job builder模块?
  2. 我们可能有多个用户并行地提出数据移动请求,因此需要一种方法来创建多个作业并以适当的顺序运行它们。
@Bean
public Job loadDataJob(JobCompletionNotificationListener listener) {
    RunIdIncrementer inc = new RunIdIncrementer();
    inc.setKey(new Date().toString());
    JobBuilder builder = jobBuilderFactory.get("loadDataJob")
            .incrementer(inc)
            .listener(listener);
    SimpleJobBuilder simpleBuilder = builder.start(preExecute());
    for(String s : getTables()){
        simpleBuilder.next(etlTable(s));
    }
    simpleBuilder.next(postExecute());
    return simpleBuilder.build();
}

@Bean
@Scope("prototype")
public Step etlTable(String tableName) {
    return stepBuilderFactory.get(tableName)
            .<Map<String,Object>, Map<String,Object>> chunk(1000)
            .reader(dbDataReader(tableName))
            .processor(processor())
            .writer(dbDataWriter(tableName))
            .build();
}

启动作业的RestController

    @RestController
public class MyController {
    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/launchjob")
    public String handle() throws Exception {
        try {
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", new Date().getTime()).toJobParameters();
            jobLauncher.run(job, jobParameters);
        } catch (Exception e) {

        }

        return "Done";
    }
}

共有1个答案

解宏扬
2023-03-14

关于第一个问题,您必须使用JavaConfiguration。此外,如果希望创建具有动态步骤数的作业(例如,每个表必须复制一个步骤),则不应该将步骤定义为spring bean。

我已经写了几个关于如何动态创造就业机会的问题的答案。看看它们,它们可能会有帮助

  • Spring批处理在tasklet中执行动态生成的步骤
  • Spring批处理重复步骤以永不结束的循环结束
  • Spring Batch--如何基于在前一步中创建的params生成并行步骤
  • Spring批处理循环读取器/处理器/写入器步骤

关于你的第二个问题,编辑了
一些评论:

@Component
@EnableBatchProcessing
@Import() // list with imports as neede
public class JobCreatorComponent {

  @Autowire
  private StepBuilderFactory stepBuilder;

  @Autowire
  private JobBuilderFactory jobBuilder;

  public Job createJob(all the parameters you need) {
     return jobBuilder.get(). ....
  }
}

@RestController
@Import(JobCreatorComponent.class)
public class MyController {
    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    JobCreatorComponent jobCreator;

    @RequestMapping("/launchjob")
    public String handle() throws Exception {
        try {
            Job job = jobCreator.createJob(... params ...);
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", new Date().getTime()).toJobParameters();
            jobLauncher.run(job, jobParameters);
        } catch (Exception e) {

        }

        return "Done";
    }
}
 类似资料:
  • 我开发了spring批处理作业,它从JDBC获取数据。我面临的问题是,它在项目启动时执行,而不管启用了什么属性。属性的值为FALSE。我试图在属性上创建一个条件bean,但它也不起作用,作业正在项目启动时执行。 遵循我的代码段。 我还试图对计划的注释进行注释,但它仍在执行作业和步骤。 //@调度(固定延迟=15000)公共无效调度ByFixed费率()抛出异常{ } 有人能告诉我这里缺少什么吗?以

  • 我正在应用程序上启动一个spring批处理作业,开始使用 spring.batch.job.names工作 不幸的是,这以某种方式延迟了tomcat服务器的启动。作业的运行时间为几分钟,因此我得到以下错误: localhost上的Tomcat v8.0服务器无法在45秒内启动。如果服务器需要更多时间,请尝试在服务器编辑器中增加超时。 问题:如何在不阻止tomcat启动的情况下运行此作业?例如异步运

  • 我正在使用spring批处理读取CSV文件并使用controller触发器将其写入DB。在启动应用程序时,在我从浏览器url中点击之前,我会在启动时看到来自阅读器的打印语句。虽然它不为我的处理器或写入器打印它,它们是在单独的类中,我已经自动连线。是因为读者是豆子吗?

  • 我有一个作业流,我希望以以下方式运行它: 作业流将从Job1开始。在Job1成功完成后,Job1将同时启动Job2和Job4。 Job2和Job4将并行运行。 在Job2成功完成后,Job2将启动Job3。 在Job4成功完成后,Job4将启动Job5。 下面是job1.xml和job1的作业启动器类的代码片段: job1.xml uijobLauncher.java “job2,Job3”对和“

  • 我遵循了spring批处理文档,无法异步运行我的作业。 因此,我从一个web容器运行该作业,该作业将通过RESTendpoint触发。 我想让JobInstance ID在完成整个作业之前传递它作为响应。因此,他们可以稍后使用JobInstance ID检查作业的状态,而不是等待。但我没能让它工作。下面是我尝试过的示例代码。请让我知道我错过了什么或错了什么。 BatchConfig创建异步JobL

  • 问题内容: 运行main方法时,将执行作业。这样我无法弄清楚如何控制作业的执行。例如,您如何安排作业,访问作业执行或设置作业参数的方式。 我试图注册自己的JobLauncher 但是当我尝试在主要方法中使用它时: 当加载上下文时,该作业再次执行,而当我尝试手动运行它时,我得到了。有没有办法防止自动作业执行? 问题答案: 通过设置可以防止作业执行 在application.properties中。或