web-dev-qa-db-ja.com

Spring BatchでItemReaderからジョブパラメーターにアクセスする方法は?

これは私のjob.xml

<job id="foo" job-repository="job-repository">
  <step id="bar">
    <tasklet transaction-manager="transaction-manager">
      <chunk commit-interval="1"
        reader="foo-reader" writer="foo-writer"
      />
    </tasklet>
  </step>
</job>

これはアイテムリーダーです。

import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("foo-reader")
public final class MyReader implements ItemReader<MyData> {
  @Override
  public MyData read() throws Exception {
    //...
  }
  @Value("#{jobParameters['fileName']}")
  public void setFileName(final String name) {
    //...
  }
}

これは、Spring Batchが実行時に言っていることです。

Field or property 'jobParameters' cannot be found on object of 
type 'org.springframework.beans.factory.config.BeanExpressionContext'

ここで何が問題なのですか? Spring 3.0でこれらのメカニズムの詳細を確認できる場所

65
yegor256

述べられているように、読者は「ステップ」スコープである必要があります。これは@Scope("step")アノテーションを介して実現できます。次のように、その注釈を読者に追加すれば機能します。

import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("foo-reader")
@Scope("step")
public final class MyReader implements ItemReader<MyData> {
  @Override
  public MyData read() throws Exception {
    //...
  }

  @Value("#{jobParameters['fileName']}")
  public void setFileName(final String name) {
    //...
  }
}

このスコープはデフォルトでは使用できませんが、batch XML名前空間を使用している場合は使用可能になります。そうでない場合は、Spring構成に次を追加すると、 Spring Batch documentation に従ってスコープが使用可能になります。

<bean class="org.springframework.batch.core.scope.StepScope" />
67
Sean Kleinjung

単一のJavaConfigクラスで ItemReader インスタンスと Step インスタンスを定義する場合。次のような _@StepScope_ および _@Value_ アノテーションを使用できます。

_@Configuration
public class ContributionCardBatchConfiguration {

   private static final String WILL_BE_INJECTED = null;

   @Bean
   @StepScope
   public FlatFileItemReader<ContributionCard> contributionCardReader(@Value("#{jobParameters['fileName']}")String contributionCardCsvFileName){

     ....
   }

   @Bean
   Step ingestContributionCardStep(ItemReader<ContributionCard> reader){
         return stepBuilderFactory.get("ingestContributionCardStep")
                 .<ContributionCard, ContributionCard>chunk(1)
                 .reader(contributionCardReader(WILL_BE_INJECTED))
                 .writer(contributionCardWriter())
                 .build();
    }
}
_

トリックは、@Value("#{jobParameters['fileName']}")アノテーションを介して挿入されるため、itemReaderにnull値を渡すことです。

Tobias Flohreの記事に感謝します。 Spring Batch 2.2 – JavaConfigパート2:JobParameters、ExecutionContext、StepScope

19
Ortomala Lokni

JobParametersを使用できるようにするには、読者をスコープ「ステップ」として定義する必要があると思いますが、注釈を使用してそれを実行できるかどうかはわかりません。

Xml-configを使用すると、次のようになります。

<bean id="foo-readers" scope="step"
  class="...MyReader">
  <property name="fileName" value="#{jobExecutionContext['fileName']}" />
</bean>

Spring Batch documentation を参照してください。

おそらく、@Scopeおよびxml-configでステップスコープを定義します。

<bean class="org.springframework.batch.core.scope.StepScope" />
13
abalogh

かなり遅いですが、@ BeforeStepメソッドに注釈を付けることでこれを行うこともできます。

@BeforeStep
    public void beforeStep(final StepExecution stepExecution) {
        JobParameters parameters = stepExecution.getJobExecution().getJobParameters();
        //use your parameters
}
11
Alex Pruss

追加の例を補足すると、JavaConfigクラスのすべてのジョブパラメーターにアクセスできます。

@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
          ....
}
2
dmotta

ジョブの実行中に、次のようにJobパラメーターを渡す必要があります。

JobParameters jobParameters= new JobParametersBuilder().addString("file.name", "filename.txt").toJobParameters();   
JobExecution execution = jobLauncher.run(job, jobParameters);  

式言語を使用して、次のように値をインポートできます。

 #{jobParameters['file.name']}
1
Premraj