2016-05-03 44 views
0

我們的SpringBatch作業只有一個步驟,包含ItemReader,ItemProcessor和ItemWriter。我們使用不同的參數同時運行相同的工作。 ItemReader是有狀態的,因爲它包含從中讀取的輸入流。如何在SpringBatch中處理有狀態的物品閱讀器

所以,我們不希望被用於每個JobInstance(工作+參數)調用的ItemReader的同一個實例。

我不太確定哪一個是這種情況的最佳「範圍」。

1)如果該步驟可以與@JobScope註釋和ItemReader是原型?

OR

2)如果步驟可以與@StepScope註釋和ItemReader是原型?

OR

3)如果兩個步驟和ItemReader被註釋爲原型?

最終的結果應該是這樣的一個新ItemReader是作業的具有不同參數識別每一個新的執行而創建(即,對於每一個新JobInstance)。

謝謝。 -AP_

回答

0

這是它從一個類實例化的角度如何去(從最低到最高的實例):

  • (每個JVM)JobScope(每個作業)
  • StepScope(每步
  • 辛格爾頓)
  • (每參考)

如果您在單個JVM上運行多個任務的原型(assum如果你不在分區的步驟中,JobScope就足夠了。如果你有一個分區的步驟,你需要StepScope。原型在所有情況下都會過度殺傷。

但是,如果這些工作在不同的JVM啓動(不分區步驟),那麼一個簡單的單例的bean會就好了。

0

沒有必要,每一個部件(步驟,ItemReader,ItemProcessor中,ItemWriter)必須是彈簧部件。例如,與SpringBatch-JAVAAPI,只有你的工作需要一個SpringBean,但不是你的腳步,在讀者與作者:

@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(); 
} 

你必須要注意的唯一的事情是,你必須調用「afterPropertiesSet方法」 - 方法一樣JdbcCurserItemReader,FlatFileItemReader /作者創建實例時:

private static <T> ItemReader<T> createDbItemReader(DataSource ds, String sql, RowMapper<T> rowMapper) throws Exception { 
    JdbcCursorItemReader<T> reader = new JdbcCursorItemReader<>(); 

    reader.setDataSource(ds); 
    reader.setSql(sql); 
    reader.setRowMapper(rowMapper); 

    reader.afterPropertiesSet(); // don't forget 
    return reader; 
} 

private static <T> ItemWriter<T> createFileWriter(Resource target, LineAggregator<T> aggregator) throws Exception { 
    FlatFileItemWriter<T> writer = new FlatFileItemWriter(); 

    writer.setEncoding("UTF-8"); 
    writer.setResource(target); 
    writer.setLineAggregator(aggregator); 

    writer.afterPropertiesSet(); // don't forget 
    return writer; 
} 

這樣一來,就沒有必要爲你與作用域費盡口舌周圍。每個工作都會有自己的步驟及其讀者和作者的實例。

這種方法的另一個好處是,你現在可以完全地動態地創建作業。