77

这是我的一部分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 中这些机制的信息?

4

7 回答 7

78

如前所述,您的读者需要在“步骤”范围内。您可以通过@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" />
于 2011-08-28T03:21:06.857 回答
32

如果您想在单个 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

于 2017-04-04T14:18:08.063 回答
20

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

@BeforeStep
    public void beforeStep(final StepExecution stepExecution) {
        JobParameters parameters = stepExecution.getJobExecution().getJobParameters();
        //use your parameters
}
于 2016-10-05T12:08:04.780 回答
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" />
于 2011-05-23T07:53:03.507 回答
3

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

@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
          ....
}
于 2018-06-19T02:58:50.883 回答
2

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

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

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

 #{jobParameters['file.name']}
于 2017-06-19T01:00:22.333 回答
-3

您是否将作业参数正确地声明为 bean?

还是您可能不小心实例化了一个没有文件名 getter 的JobParameters对象?

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

于 2011-06-04T09:11:59.493 回答