如何在Spring Batch中从ItemReader访问作业参数?


73

这是我的一部分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中,我在哪里可以了解有关这些机制的更多信息?

Answers:


75

如前所述,您的阅读器需要进行“逐步”调整。您可以通过@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) {
    //...
  }
}

该范围默认情况下不可用,但是如果您正在使用batchXML名称空间,则该范围将不可用。如果不是这样,请根据Spring Batch文档,在Spring配置中添加以下内容以使作用域可用:

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

8
StepScope现已默认
查拉图斯特拉

1
自v2.2以来,还有一个快捷方式,将@StepScope与@Bean一起使用
Guillaume

@Scope("step")不适用于我,@StepScope但是对我
有用

春天真的不喜欢最后一堂课
gstackoverflow

24

如果要在单个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();
    }
}

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

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


我们将如何测试呢?
RBz

20

太晚了,但是您也可以通过注释@BeforeStep方法来做到这一点:

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

8
仅当作业参数的使用未更改ItemReader的状态时,这才有用。如果例如使用它们来指定要读取的数据,则读取器的并发执行可能会导致错误的行为。
tveon

@tveon,这可以通过在声明阅读器bean时使用StepScope来解决,对吗?
Kajzer

@Kajzer是的,除非以后再使用阅读器来完成同一工作,否则您也可以使用JobScope
tveon

14

为了能够使用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" />

我对注解特别感兴趣。这种配置格式已经过时并有文档记录。
yegor256

您没有表示只对仅注释的解决方案感兴趣。谢谢您的投票。
abalogh 2011年

3

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

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

2

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

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

通过使用表达式语言,我们可以按如下所示导入值:

 #{jobParameters['file.name']}

-2

您是否像bean一样正确地声明jobparameters为map?

还是您意外地实例化了JobParameters没有获取文件名对象?

欲了解更多关于表达式语言,你可以找到春天文档中的信息在这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.