Как получить доступ к параметрам задания из 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'

что здесь не так? Где я могу узнать больше об этих механизмах весной 3.0?

7 57

7 ответов:

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

<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>

смотрите дальше на документация партии весны.

возможно, это работает с помощью @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
}

если вы хотите определить свой 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();
    }
}

трюк состоит в том, чтобы передать нулевое значение в itemReader, так как оно будет введено через @Value("#{jobParameters['fileName']}") Примечание.

спасибо Тобиасу флору за его статью:Весенняя Партия 2.2-JavaConfig Часть 2: JobParameters, ExecutionContext и StepScope

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

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

вы объявили jobparameters как карту правильно, как Боб?

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

для получения дополнительной информации о языке выражений вы можете найти информацию в весенней документации здесь.