如何将简单的字符串传递给Spring Batch Job

时间:2017-03-07 21:09:19

标签: java spring spring-batch

我有一个复杂的工作流程,我在JobStep中有3个独立的工作,然后我从Job调用JobStep。将有四个JobSteps将与调用作业并行运行。

我需要将一个字符串作为参数传递给它们。

有些简化的代码:

我的主要看起来像这样:

public static void main(String[] args)  {
        SpringApplication.run(SomeApplication.class, args);
}

其中一个JobSteps看起来像

@Bean
public JobStep jobStep1(<snip>){
        <snip for clarity>
        JobStep jobStep = new JobStep() ;
        jobStep.setJob(jobs.get(jobName)
                .incrementer(new RunIdIncrementer()).listener(listener)
                .start(Flow1)
                .next(Flow2)
                .next(Flow3)
                .end().build());
        jobStep.setJobRepository(jobRepository);
        jobStep.setJobLauncher(jobLauncher);
        return jobStep; 
 }

运行其余部分的最高职位看起来像

@Bean
    public Job parentJob(<snip>) {

        Flow childJobFlow = new FlowBuilder<SimpleFlow>("childJob").start(job1).build();
        Flow childJobFlow2 = new FlowBuilder<SimpleFlow>("childJob2").start(job2).build();

        FlowBuilder<SimpleFlow> builder = new FlowBuilder<SimpleFlow>("jobFlow");
        Flow jobFLow = builder.split(new SimpleAsyncTaskExecutor()).add(childJobFlow,childJobFlow2).build();

        return jobs.get("parentJob")
                .incrementer(new RunIdIncrementer()).listener(listener)
                .start(jobFLow)             
                .end().build();

    }

我需要每个JobStep获取不同的字符串。

1 个答案:

答案 0 :(得分:0)

我能够像Nghia Do在评论中建议的那样使用Partitioner。使用分区程序,我可以将字符串推送到上下文,然后在@Before Step中检索它。

在我的ItemReader中,我有:

@BeforeStep
public void beforeStep(StepExecution stepExecution) throws Exception {
    this.stepExecution = stepExecution.getExecutionContext();
    this.keyString =  stepExecution.getString("keyString");
}

The Paritioner

@Override
public Map<String, ExecutionContext> partition(int gridSize) {
    Map<String, ExecutionContext> partitionMap = new HashMap<String, ExecutionContext>();
    List<String> codes = getCodes();

    for (String code : codes)
    {
        ExecutionContext context = new ExecutionContext();
        context.put("keyString", code);
        partitionMap.put(code, context);
    }
    return partitionMap;
}

getCodes现在只是一个占位符函数,它返回一个用于测试的字符串列表。最终它将取代更有用的东西。

private List<String> getCodes() {
        ArrayList<String> result = new ArrayList<String>();
        result.add("One");
        result.add("Two");  
        result.add("Three");    
        result.add("Four"); 
        result.add("Five"); 
        result.add("Six");
        result.add("Seven");
        return result;
    }

然后,为了完成步骤,我做了一个主要步骤,调用了我现有的步骤:

@Bean
    public Step masterStep(@Value("#{proccessFilesStep}") Step readFilesStep) {

        return  stepBuilders.get("masterStep")
                .partitioner(readFilesStep)
                .partitioner("proccessFilesStep", partitioner())
                .taskExecutor(taskExecutor())
                .build();

    }

stepBuilders是:

@Autowired
    private StepBuilderFactory stepBuilders;

不得不在网上结合20个不同的例子来获得所有的琐事,所以我把它们全部放在这个答案中,供下一个需要它的人使用。