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 ?
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 Step
s 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;
}
}