Подтвердить что ты не робот

Как получить доступ к параметрам задания из ItemReader, в Spring Batch?

Это часть моего 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?

4b9b3361

Ответ 1

Как уже было сказано, ваш читатель должен быть "шаг". Вы можете выполнить это с помощью аннотации @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 Пакетная документация:

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

Ответ 2

Чтобы иметь возможность использовать параметры jobParameters, я думаю, вам нужно определить своего читателя как "шаг шага", но я не уверен, что вы можете сделать это с помощью аннотаций.

Используя xml-config, он будет выглядеть следующим образом:

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

См. далее Spring Пакетная документация.

Возможно, это работает с помощью @Scope и определения области шага в вашем xml-config:

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

Ответ 3

Довольно поздно, но вы также можете сделать это, аннотируя метод @BeforeStep:

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

Ответ 4

Если вы хотите определить экземпляр ItemReader и ваш экземпляр Step в одном классе JavaConfig. Вы можете использовать аннотации @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 Пакет 2.2 - JavaConfig Часть 2: JobParameters, ExecutionContext и StepScope

Ответ 5

При выполнении задания нам необходимо передать параметры работы следующим образом:

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

используя язык выражения, мы можем импортировать значение следующим образом:

 #{jobParameters['file.name']}

Ответ 6

Вы правильно указали параметры работы как карту как bean?

Или вы случайно не создали экземпляр объекта JobParameters, у которого нет имени для имени файла?

Подробнее о языке выражения вы можете найти в Spring документации здесь.