1

Perfect solution for dynamic step creationin Spring Batch. Just that I am not able to get parameters into this , which will decide what step need to be executed or how can pass steps Array ?

<pre>@Bean
public Job job() {
    Step[] stepsArray = // create your steps array or pass it as a parameter
    SimpleJobBuilder jobBuilder = jobBuilderFactory.get("mainCalculationJob")
            .incrementer(new RunIdIncrementer())
            .start(truncTableTaskletStep());
    for (Step step : stepsArray) {
        jobBuilder.next(step);
    }
    return jobBuilder.build();
}</pre>

Thanks

  • I guess you took this snippet from here: https://stackoverflow.com/a/54862683/5019386. `I am not able to get parameters into this`: which parameters are you referring to? Are those job parameters or parameters passed to the JVM using `-D` or something else? – Mahmoud Ben Hassine Jul 21 '20 at 17:16
  • Hi Hassine, I am big fan of yours . You are correct I had gone through code snippet, actually, i am trying to get sequence of steps ( s1,s2,s3 or S4 ,S5) from Db and according to that job should have steps configured, for that i need to get that (steps array ) in above code, as you see " // create your steps array or pass it as a parameter" i am looking how to pass this step array as parameter and get in above function – GovindSMahara Jul 22 '20 at 04:29
  • Thank you! I added an answer with a complete example. Hope it helps. – Mahmoud Ben Hassine Jul 22 '20 at 07:47

1 Answers1

1

i am looking how to pass this step array as parameter and get in above function

Here is an example of how to pass the steps array as a parameter:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.SimpleJobBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    public MyJobConfiguration(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
    }

    public Step initialStep() {
        return stepBuilderFactory.get("initialStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("initial step");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }
    
    @Bean
    public Step[] dynamicSteps() {
        // load steps sequence from db and create steps here
        Step step1 = stepBuilderFactory.get("step1")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("hello");
                    return RepeatStatus.FINISHED;
                })
                .build();
        Step step2 = stepBuilderFactory.get("step2")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("world");
                    return RepeatStatus.FINISHED;
                })
                .build();
        return new Step[]{step1, step2};
    }

    @Bean
    public Job job(Step[] dynamicSteps) {
        SimpleJobBuilder jobBuilder = jobBuilderFactory.get("job")
                .start(initialStep());
        for (Step step : dynamicSteps) {
            jobBuilder.next(step);
        }
        return jobBuilder.build();
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}

Nothing related to Spring Batch here, this is Spring dependency injection: passing an array of beans of type Step as a parameter to a another bean definition method (of type Job).

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50
  • Thanks a lot , it worked as i need. I saw your presentation on "https://www.infoq.com/presentations/batch-lifecycle/" Batch Processing 2019 Good One. Thanks for doing great work – GovindSMahara Jul 23 '20 at 10:26
  • You are welcome, I'm always happy to help! Thank you, glad you liked the presentation. – Mahmoud Ben Hassine Jul 23 '20 at 11:11