为了能在ItemReader, ItemWriter, ItemProcessor中读取JobParameters中的参数,有两个方法:
- 使用 @BeforeStep,如下示例
public class PersonItemProcessor implements ItemProcessor<Person, Person> {
JobParameters jobParameters;
@BeforeStep
public void beforeStep(final StepExecution stepExecution) {
jobParameters = stepExecution.getJobParameters();
log.info("jobParameters: {}", jobParameters);
}
- 把相应的Bean定义成@StepScope,再用@Value直接注入.
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean @StepScope
public FlatFileItemReader<Person> reader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource("sample-data.csv"))
.delimited()
.names(new String[]{"firstName", "lastName"})
.fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}})
.build();
}
@Bean @StepScope
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean @StepScope
public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<Person>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("...")
.dataSource(dataSource)
.build();
}
@Bean("importUserJob")
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean //这个不要定义StepScope
public Step step1(JdbcBatchItemWriter<Person> writer) {
重点注意的是,要把ItemReader, ItemWriter, ItemProcessor声明成StepScope,而Job和Step本身不能申明成StepScope
然后在ItemReader, ItemWriter, ItemProcessor中可以直接注入参数了:
public class PersonItemProcessor implements ItemProcessor<Person, Person> {
@Value("#{jobParameters['dataUnitId']}")
private Long dataUnitId;