2016-05-03 4 views
0

SpringBatchジョブには、ItemReader、ItemProcessor、およびItemWriterを持つ単一のステップがあります。我々は、異なるパラメータを用いて同じ仕事を同時に実行している。 ItemReaderは読み込み元の入力ストリームを含むため、ステートフルです。SpringBatchでステートフルなアイテムリーダーを処理する方法

したがって、すべてのJobInstance(Job + Parameters)呼び出しでItemReaderの同じインスタンスを使用する必要はありません。

この状況では、「スコープ設定」が最適ではありません。

1)ステップに@JobScopeとItemReaderをアノテートしてプロトタイプを作成する必要がありますか?

OR

2)ステップは@StepScopeとItemReaderで注釈されるべきプロトタイプなりますか?

OR

3)がステップとItemReader両方をプロトタイプとして注釈されるべきか?

最終的な結果は、異なる識別パラメータを持つ(つまり、新しいJobInstanceごとに)ジョブの新しい実行ごとに新しいItemReaderが作成されるようにする必要があります。

ありがとうございました。ここで -AP_

答えて

0

は、それが(少なくともからほとんどの場合に)クラスのインスタンス化の観点からどのようになるのです:

  • JobScope
  • StepScope(ジョブごと)(ステップあたり(JVMあたり)

    • シングルトン(あなたは、単一のJVMで実行している複数のジョブを持っている場合は

    )参照あたり)

  • プロトタイプ(assumパーティション化されていないStepであれば、JobScopeで十分です。分割されたステップがある場合は、StepScopeが必要です。プロトタイプはすべてのシナリオで過度のものになるでしょう。

    しかし、これらのジョブが異なるJVM(パーティション化されたステップではない)で起動している場合、単純なシングルトンBeanはうまくいくでしょう。

  • 0

    すべてのコンポーネント(Step、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」-methods 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; 
    } 
    

    この方法は、あなたがスコープの周り面倒にするために必要はありません。すべての職務には、そのステップとその読者と作家の独自のインスタンスがあります。

    このアプローチのもう1つの利点は、ジョブを完全に動的に作成できることです。

    関連する問題