これは私の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でこれらのメカニズムの詳細を確認できる場所
述べられているように、読者は「ステップ」スコープである必要があります。これは@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" />
単一の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
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" />
かなり遅いですが、@ BeforeStepメソッドに注釈を付けることでこれを行うこともできます。
@BeforeStep
public void beforeStep(final StepExecution stepExecution) {
JobParameters parameters = stepExecution.getJobExecution().getJobParameters();
//use your parameters
}
追加の例を補足すると、JavaConfigクラスのすべてのジョブパラメーターにアクセスできます。
@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
....
}
ジョブの実行中に、次のようにJobパラメーターを渡す必要があります。
JobParameters jobParameters= new JobParametersBuilder().addString("file.name", "filename.txt").toJobParameters();
JobExecution execution = jobLauncher.run(job, jobParameters);
式言語を使用して、次のように値をインポートできます。
#{jobParameters['file.name']}