39

I have a requirement where I need to process files based on the rest call in which I get the name of the file, I am adding it to the job parameter and using it while creating the beans.

I am creating step scope Beans for (reader,writer) and using the job parameter.I am starting the job in a new thread as I am using asynchronus task exceutor to launch the job and my question is how will the beans be created by spring when we define @StepScope

jobParametersBuilder.addString("fileName", request.getFileName());
jobExecution = jobLauncher.run(job, jobParametersBuilder.toJobParameters());
@Bean
public JobLauncher jobLauncher() {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository());
    jobLauncher.setTaskExecutor(asyncTaskExecutor());
    return jobLauncher;
}

@Bean
@StepScope
public ItemWriter<Object> writer(@Value ("#{jobParameters['fileName']}"String    fileName) {
    JdbcBatchItemWriter<Object> writer = new JdbcBatchItemWriter<>();
    writer.setItemSqlParameterSourceProvider(
        new BeanPropertyItemSqlParameterSourceProvider<Object>());
    writer.setSql(queryCollection.getquery());
    writer.setDataSource(dataSource(fileName));
    return writer;
}
1
  • 2
    this @Value ("#{jobParameters['fileName']}"String fileName) { that you have provided in your question is a killer. thnx for sharing that.
    – Faraz
    Sep 25, 2018 at 15:24

1 Answer 1

79

A spring batch StepScope object is one which is unique to a specific step and not a singleton. As you probably know, the default bean scope in Spring is a singleton. But by specifying a spring batch component being StepScope means that Spring Batch will use the spring container to instantiate a new instance of that component for each step execution.

This is often useful for doing parameter late binding where a parameter may be specified either at the StepContext or the JobExecutionContext level and needs to be substituted for a placeholder, much like your example with the filename requirement.

Another useful reason to use StepScope is when you decide to reuse the same component in parallel steps. If the component manages any internal state, its important that it be StepScope based so that one thread does not impair the state managed by another thread (e.g, each thread of a given step has its own instance of the StepScope component).

2
  • But do you lose JdbcPagingItemReader then? Jul 1, 2020 at 15:54
  • @Naros but if you are instantiating a "new" instance for each StepExecution using StepScope, than that means restarting the Job and resuming where you left off is impossible right? Since no state will be saved from the previous execution and it will be a new instance? Jul 7, 2021 at 19:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.