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