Как получить доступ к параметрам задания из 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?
Ответы
Ответ 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 документации здесь.