Java 如何在SpringBatch中从ItemReader访问作业参数?

Java 如何在SpringBatch中从ItemReader访问作业参数?,java,spring,spring-batch,Java,Spring,Spring Batch,这是我的作业的一部分。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" />

这是我的
作业的一部分。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>

这里怎么了?在哪里我可以在Spring 3.0中阅读更多关于这些机制的信息?

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

使用xml配置,它将如下所示:

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

您是否正确地将jobparameters声明为map作为bean

或者您是否偶然实例化了一个没有文件名getter的对象


有关表达式语言的更多信息,您可以在Spring文档中找到。

如前所述,您的读者需要确定“步骤”范围。您可以通过
@Scope(“步骤”)
注释来实现这一点。如果您将该注释添加到阅读器中,它应该对您有用,如下所示:

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) {
    //...
  }
}

很晚了,但您也可以通过注释@BeforeStep方法来实现这一点:

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

如果希望在单个JavaConfig类中定义实例和实例。您可以使用和注释,例如:

@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();
    }
}
@配置
公共类贡献CardBatchConfiguration{
私有静态最终字符串将被注入=null;
@豆子
@步进镜
公共FlatFileItemReader贡献CardReader(@Value(“#{jobParameters['fileName']}”)字符串贡献CardCsvFileName){
....
}
@豆子
步骤ingestContributionCardStep(项目阅读器){
返回stepBuilderFactory.get(“ingestContributionCardStep”)
.chunk(1)
.reader(捐款卡阅读器(将被注入))
.writer(contributionCardWriter())
.build();
}
}
诀窍是将空值传递给itemReader,因为它将通过
@value(“#{jobParameters['fileName']}”)
注释注入


感谢Tobias Flohre的文章:

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

JobParameters jobParameters= new JobParametersBuilder().addString("file.name", "filename.txt").toJobParameters();   
JobExecution execution = jobLauncher.run(job, jobParameters);  
 #{jobParameters['file.name']}
通过使用表达式语言,我们可以按如下方式导入值:

JobParameters jobParameters= new JobParametersBuilder().addString("file.name", "filename.txt").toJobParameters();   
JobExecution execution = jobLauncher.run(job, jobParameters);  
 #{jobParameters['file.name']}

作为补充,您可以访问JavaConfig类中的所有作业参数:

@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
          ....
}
@Bean
@步进镜
公共项StreamReader读取器(@Value(#{jobParameters}”)映射作业参数){
....
}

我对注释特别感兴趣。这种配置格式很旧,并且有文档记录。您还没有声明您只对仅注释的解决方案感兴趣。无论如何,感谢您的投票。
StepScope
现在默认可用还有一个快捷方式,因为v2.2与@Bean
@Scope(“step”)
一起使用对我不起作用,而
@StepScope
didSpring并不真正喜欢final类我们可以在方法上注释@StepScope这只有用,如果作业参数的使用没有改变ItemReader的状态。例如,如果它们用于指定要读取的数据,则读卡器的并发执行可能会导致错误行为。@tveon,这可以通过在声明读卡器bean时使用StepScope来解决,对吗?@Kajzer yes,除非以后在同一作业中重新使用读卡器,然后您还可以使用
JobScope
解决这个问题,我们将如何测试它?
 #{jobParameters['file.name']}
@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
          ....
}