如何在Spring批处理中从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的这些机制?

如上所述,您的阅读器需要“一步”的范围。 您可以通过@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命名空间的话。 如果你不是这样,那么在Springconfiguration中添加以下内容将使得范围可用,按照Spring Batch文档 :

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

为了能够使用jobParameters,我认为你需要将你的阅读器定义为范围的“步骤”,但我不确定是否可以使用注释来完成。

使用xml-config,它会像这样:

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

请参阅Spring Batch文档 。

也许它通过使用@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类中定义你的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(); } } 

诀窍是将一个空值传递给itemReader,因为它将通过@Value("#{jobParameters['fileName']}")注释注入。

感谢Tobias Flohre的文章: Spring Batch 2.2 – JavaConfig第2部分:JobParameters,ExecutionContext和StepScope

在执行作业时,我们需要传递Job参数,如下所示:

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

通过使用expression式语言,我们可以如下导入值:

  #{jobParameters['file.name']} 

你是否像bean一样正确地声明了jobparameters?

或者你是否偶然实例化了一个JobParameters对象,该对象没有getter的文件名?

有关expression式语言的更多信息,可以在这里查找Spring文档中的信息 。