In Spring boot batch, should the itemWriter, itemProcessor, itemWriter be step-scoped?

362 views Asked by At

From the tutorial of Spring Batch – Tasklets vs Chunks, When define a ItemReader, ItemProcessor, ItemWriter, should we give them an annotation of @StepScope?

Let me give a example code:

LineReader has only one instance, but it has a member fu. So if in multithreads env, will it cause error?

Why in this tutorial, it was not annotated by @StepScope?

ChunksConfig.java

....
    @Bean // here is no @StepScope, but I think it should have a @StepScope
    public ItemReader<Line> itemReader() {
        return new LineReader();
    }

    @Bean
    protected Step processLines(ItemReader<Line> reader, ItemProcessor<Line, Line> processor, ItemWriter<Line> writer) {
        return steps.get("processLines").<Line, Line> chunk(2)
          .reader(reader)
          .processor(processor)
          .writer(writer)
          .build();
    }
....

LineReader.java

public class LineReader implements ItemReader<Line>, StepExecutionListener {

    private final Logger logger = LoggerFactory.getLogger(LineReader.class);
    private FileUtils fu;

    @Override
    public void beforeStep(StepExecution stepExecution) {
        fu = new FileUtils("taskletsvschunks/input/tasklets-vs-chunks.csv");
        logger.debug("Line Reader initialized.");
    }

    @Override
    public Line read() throws Exception {
        Line line = fu.readLine();
        if (line != null) logger.debug("Read line: " + line.toString());
        return line;
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        fu.closeReader();
        logger.debug("Line Reader ended.");
        return ExitStatus.COMPLETED;
    }
}
2

There are 2 answers

2
Jiandong On

Q1: When define a ItemReader, ItemProcessor, ItemWriter, should we give them an annotation of @StepScope?

from the notes in late-binding

Any bean that uses late binding must be declared with scope="step". See Step Scope for more information. A Step bean should not be step-scoped. If late binding is needed in a step definition, the components of that step (tasklet, item reader or writer, and so on) are the ones that should be scoped instead.

Q2: if itemReader only has one instance, in multithreads env, will it cause error?

if the job is running and the reader is singleton, and you use multi-threads to read the source, it depends on how you partition the data, no issues will happen if data segregation is correct.

PS: there do have some practical limitations when using job-scoped beans in multi-threaded or partitioned steps. see the notes in job-scope session

1
Tấn Đại On

spring batch @bean only one time init when you start sever so if you want @bean update and init data inside body function like ItemReader,... use @StepScope