如何在SpringBatch

时间:2016-05-03 15:07:49

标签: spring-batch

我们的SpringBatch作业只有一个步骤,包含ItemReader,ItemProcessor和ItemWriter。我们使用不同的参数同时运行相同的工作。 ItemReader是有状态的,因为它包含从中读取的输入流。

因此,我们不希望ItemReader的相同实例用于每个JobInstance(Job + Parameters)调用。

我不太确定哪种情况最适合这种情况。

1)是否应该使用@JobScope注释Step并将ItemReader作为原型?

OR

2)是否应使用@StepScope注释步骤,并将ItemReader作为原型?

OR

3)Step和ItemReader都应该注释为Prototype吗?

最终结果应该是为每个新的Job执行创建一个新的ItemReader,使用不同的标识参数(即每个新的JobInstance)。

感谢。 -AP _

2 个答案:

答案 0 :(得分:0)

以下是从类实例化角度(从最少到大多数实例)的过程:

  • Singleton(每个JVM)
  • JobScope(每份工作)
  • StepScope(每步)
  • 原型(每个参考文献)

如果您在一个JVM中运行多个作业(假设您不在分区步骤中,JobScope就足够了。如果您有分区步骤,您将需要StepScope。原型在所有情况下都会过度。

但是,如果这些作业在不同的JVM中启动(而不是分区步骤),那么一个简单的Singleton bean就可以了。

答案 1 :(得分:0)

不需要每个组件(Step,ItemReader,ItemProcessor,ItemWriter)都必须是spring组件。例如,使用SpringBatch-JavaApi,只有你的Job需要是一个SpringBean,而不是你的Step,Readers和Writers:

$url = 'http://dev.testserver.com/test.php';
        $data_string = json_encode($fields);
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_POST, 1); 
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
        curl_setopt($curl, CURLOPT_POSTFIELDS,$data_string );                                                                  
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);                                                                      
        $curl_response = curl_exec($curl);

您唯一需要注意的是在创建JdbcCurserItemReader,FlatFileItemReader / Writer等实例时必须调用“afterPropertiesSet”方法:

    @Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Bean
public Job job() throws Exception {
    return this.jobs.get(JOB_NAME) // create jobbuilder
            .start(step1()) // add step 1
            .next(step2()) // add step 2
            .build(); // create job
}

@Bean
public Job job() throws Exception {
    return this.jobs.get(JOB_NAME) // create jobbuilder
            .start(step1(JOB_NAME)) // add step 1
            .next(step2(JOB_NAME)) // add step 2
            .build(); // create job
}

private Step step1(String jobName) throws Exception {

    return steps.get(jobName + "_Step_1").chunk(10) //
            .faultTolerant() //
            .reader(() -> null) // you could lambdas
            .writer(items -> {
            }) //
            .build();
}

private Step step2(String jobName) throws Exception {
    return steps.get(jobName + "_Step_2").chunk(10) //
            .faultTolerant() //
            .reader(createDbItemReader(ds, sqlString, rowmapper)) //
            .writer(createFileWriter(resource, aggregator)) //
            .build();
}

通过这种方式,您无需为Scopes烦恼。每个工作都有自己的步骤及其读者和作家的实例。

这种方法的另一个优点是,您现在可以动态地创建作业。