Как получить доступ к параметрам задания из ItemReader, в Spring Batch? - PullRequest
64 голосов
/ 21 мая 2011

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

Ответы [ 7 ]

66 голосов
/ 28 августа 2011

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

<bean class="org.springframework.batch.core.scope.StepScope" />
19 голосов
/ 04 апреля 2017

Если вы хотите определить ваш 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']}").

Спасибо Тобиасу Флоре за его статью: Spring Batch 2.2 - JavaConfig, часть 2: JobParameters, ExecutionContext и StepScope

13 голосов
/ 23 мая 2011

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

При использовании xml-config это будет выглядеть так:

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

Подробнее см. В документации Spring Batch .

Возможно, это работает с использованием @Scope и определением области действия шага в вашей xml-конфигурации:

<bean class="org.springframework.batch.core.scope.StepScope" />
11 голосов
/ 05 октября 2016

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

@BeforeStep
    public void beforeStep(final StepExecution stepExecution) {
        JobParameters parameters = stepExecution.getJobExecution().getJobParameters();
        //use your parameters
}
2 голосов
/ 19 июня 2018

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

@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
          ....
}
1 голос
/ 19 июня 2017

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

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

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

 #{jobParameters['file.name']}
0 голосов
/ 04 июня 2011

Вы объявили параметры задания как map должным образом как bean-компонент?

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...