如何制作参数化的工作?

时间:2018-11-15 12:42:06

标签: spring spring-boot spring-batch

我正在尝试向阅读器发送参数。

public JpaPagingItemReader<Person> reader(@Value("#{jobParameters['PersonId']}")
String id){
    JpaPagingItemReader<Person> reader = new JpaPagingItemReader<Person>();
    reader.setEntityManagerFactory(emf);
    reader.setQueryString("SELECT p from "+Person.class.getName()+" p where Id = "+id);
    reader.setPageSize(10);
    return reader;
}

这又将希望参数来自步骤和作业方法。

@Bean
public Step step(String id){
    return stepBuilder.get("step").<Person,Person>chunk(100).reader(reader(id))
        .processor(processor())
        .writer(writer()).build();
}

@Bean
public Job personJob(String id){
    return jobBuilder.get("personJob").incrementer(new RunIdIncrementer()).flow(step(id)).end().build(); 
}

我的main方法实现了CommandLineRunner,并且run方法被覆盖如下-

@Override
public void run(String... args) throws Exception {
    JobParameters parameters = new JobParametersBuilder()
        .addString("PersonId", "1")
        .toJobParameters();
    jobLauncher.run(job, parameters);
}

上面的方法将不接受jobParameters,因为jobLauncher.run(job,parameters)期望job没有自变量,但它不接受jobLauncher.run(job(id),parameters)

收到的错误为-

Parameter 0 of method personJob in com.example.JobConfig required a bean of type 'java.lang.String' that could not be found.

有什么办法可以使我的读者获得id

2 个答案:

答案 0 :(得分:1)

由于public Step step(String id)等效于public Step step(@Autowired String id),并且没有在上下文中定义String Bean,因此会出现此异常。

要从JobParameters对象传递ID,您需要声明JobParameters jobParameters bean,并使用@Value("#{jobParameters['PersonId']}"或直接使用jobParameters bean。

我对Spring Batch不熟悉,但我想配置应该类似于以下内容:

@Configuration
public class PersonJobConfig {

    @Bean
    public JobParameters jobParameters() {
        return new JobParametersBuilder().addString("PersonId", "1").toJobParameters();
    }

    @Bean
    public Step step(JobParameters jobParameters){
        return stepBuilder.get("step").<Person,Person>chunk(100).reader(reader(jobParameters.getString("PersonId"))
            .processor(processor())
            .writer(writer()).build();
    }

    @Bean
    public Job personJob(JobParameters jobParameters){
        return jobBuilder.get("personJob").incrementer(new RunIdIncrementer()).flow(step(jobParameters.getString("PersonId"))).end().build(); 
    }

}

答案 1 :(得分:1)

您的阅读器应该具有逐步作用域,以便能够注入作业参数:

@Bean
@StepScope
public JpaPagingItemReader<Person> reader(@Value("#{jobParameters['PersonId']}") String id){
   JpaPagingItemReader<Person> reader = new JpaPagingItemReader<Person>();
   reader.setEntityManagerFactory(emf);
   reader.setQueryString("SELECT p from "+Person.class.getName()+" p where Id = "+id);
   reader.setPageSize(10);
   return reader;
}

这在参考文档的StepScope部分中进行了说明。

您无需在step和job Bean方法的签名中传播ID,您可以按以下方式传递null

@Bean
public Step step() {
   return stepBuilder.get("step")
    .<Person,Person>chunk(100)
    .reader(reader(null))
    .processor(processor())
    .writer(writer())
    .build();
}

@Bean
public Job personJob(){
    return jobBuilder.get("personJob")
       .incrementer(new RunIdIncrementer())
       .flow(step())
       .end()
       .build(); 
}

最后,您的run方法是正确的,没有什么可更改的。

希望这会有所帮助。