如何启动工作

How to launch a Job

我目前正在尝试在我的 Spring 应用程序中以编程方式启动作业。

这是我的实际代码:

public void launchJob(String[] args)
            throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException,
            JobInstanceAlreadyCompleteException {
        
    String jobName = args[0];

    JobLauncher jobLauncher = context.getBean(JobLauncher.class);
    Job job = context.getBean(jobName, Job.class);
    JobParameters jobParameters = getJobParameters(args);


    JobExecution jobExecution = jobLauncher.run(job, jobParameters);
    BatchStatus batchStatus = jobExecution.getStatus();
}

以及我如何启动它:

String[] args = {"transformXML2CSV", "myFile.xml", "myFile.csv"};
springBatchJobRunner.launchJob(args);

但是我在启动过程中遇到了一些麻烦,首先是检索应用程序上下文,我的第一次尝试是用 @Service 注释我的 class 并使用 @Autowired像这样:

@Autowired
private ApplicationContext context;

但是通过这种方式我的 context 总是空的。

我的第二次尝试是通过这种方式获取上下文:

ApplicationContext context = new AnnotationConfigApplicationContext(SpringBatchNoDatabaseConfiguration.class);

SpringBatchNoDatabaseConfiguration 是我的 @Configuration,工作在里面。

使用这个我的 context 不是空的,但我有一个奇怪的行为,我不明白为什么以及如何防止这种情况:

我 运行 来自 processor classlaunchJob 函数,然后当我通过 AnnotationConfigApplicationContext 获得 context 时,我的 processor class 正在重建我有一个 NullPointerException 停止所有进程。

我真的不明白最后一部分,为什么它在我获取上下文时重新启动我的 processor class

似乎第二个 Spring 上下文是用指令 new AnnotationConfigApplicationContext(SpringBatchNoDatabaseConfiguration.class) 初始化的,所以 Spring 第二次初始化了你的 bean。

我建议你使用 Spring 启动到 automatically launch your jobs at sartup

如果您不想使用 Spring 手动启动和启动作业,您的 main 方法应该如下所示:

public static void main(String[] args){
    String[] localArgs = {"transformXML2CSV", "myFile.xml", "myFile.csv"};
    ApplicationContext context = new AnnotationConfigApplicationContext(SpringBatchNoDatabaseConfiguration.class);
    Job job = context.getBean(Job.class);
    JobLauncher jobLauncher = context.getBean(JobLauncher.class);
    JobParameters jobParameters = getJobParameters(localArgs);
    jobExecution = jobLauncher.run(job, jobParameters);
    // Ohter code to do stuff after the job ends...
}

注意这段代码要根据自己的需要来完成。 class SpringBatchNoDatabaseConfiguration 必须用 @Configuration@EnableBatchProcessing 注释并且应该定义你的工作的 beans like this

您还可以将 Spring 批处理 class CommandLineJobRunner 与您的 java 配置一起使用,如下所述: 省去了写上面的代码

如上面的评论所述,您 运行 一个 parent 批次(带有 spring-batch),此时需要您的工作来处理 xml 文件。

我建议您保持相同的 spring-batch 上下文和 运行 处理 xml 文件作业作为 parent 作业的嵌套作业。您可以使用 JobStep class 和 spring 批量控制步骤流程功能来做到这一点。例如,这是您的 parent 工作想要的:

public Job parentJob(){
   JobParameters processXmlFileJobParameters = getJobParameters(String[]{"transformXML2CSV", "myFile.xml", "myFile.csv"});
   return this.jobBuilderFactory.get("parentJob")
            .start(firstStepOfParentJob())
            .on("PROCESS_XML_FILE").to(processXmlFileStep(processXmlFileJobParameters)
            .from(firstStepOfParentJob()).on("*").to(lastStepOfParentJob())
            .from(processXmlFileStep(processXmlFileJobParameters))
            .next(lastStepOfParentJob())
            .end().build();
}

public Step firstStepOfParentJob(){
   return stepBuilderFactory.get("firstStepOfParentJob")
          // ... depends on your parent job's business
          .build();
}

public Step lastStepOfParentJob(){
    return stepBuilderFactory.get("lastStepOfParentJob")
          // ... depends on your parent job's business
          .build();
} 

public Step processXmlFileStep(JobParameters processXmlFileJobParameters){
    return stepBuilderFactory.get("processXmlFileStep")
                             .job(processXmlFileJob())
                             .parametersExtractor((job,exec)->processXmlFileJobParameters)
                             .build();
}

public Job processXmlFileJob(){
    return jobBuilderFactory.get("processXmlFileJob")
          // ... describe here your xml process job
          .build();
}