Search code examples
springspring-bootspring-batchbatch-processing

How to share value between multiple ItemProcessor runs , in spring batch?


I have to set the line of a record in a csv file within the record object when processing it before passing it to the writer . What i want to achieve is to declare a global variable lets say line = 1 and each time an itemProcessor runs it should assign its value to the current item , and increment its value by 1 line++.

How can i share a variable over multiple itemProcessor runs ?


Solution

  • You can leverage the ExecutionContext to save the line variable of either the StepExecution if you only need the ExecutionContext in the single Step or JobExecution if you need the ExecutionContext in other Steps of the Job.

    Inject either execution in your ItemProcessor:

    @Value("#{stepExecution.jobExecution}") JobExecution jobExecution
    

    or

    @Value("#{stepExecution}") StepExecution stepExecution
    

    Taking JobExecution as an example:

    @StepScope
    @Bean
    public MyItemProcessor myItemProcessor(@Value("#{stepExecution.jobExecution}") JobExecution jobExecution) {
        return new MyItemProcessor(jobExecution);
    }
    
    @Bean
    public Step myStep() {
        return stepBuilderFactory.get("myStep")
            ...
            .processor(myItemProcessor(null))
            ...
            .build()
    }
    
    
    public class MyItemProcessor implements ItemProcessor<MyItem, MyItem> {
    
        private ExecutionContext executionContext;
    
        public MyItemProcessor() {
            this.executionContext = jobExecution.getExecutionContext();
        }
    
        @Override
        public MyItem process(MyItem item) throws Exception {
            // get the line from previous item processors, if exists, otherwise start with 0
            int line = executionContext.getInt("myLineKey", 0);
            item.setLine(line++);
            // save the line for other item processors
            item.put("myLineKey", line);
            return item;
        }
    
    }