简体   繁体   中英

When constructors for ItemReader, ItemProcessor, ItemWriter are called in Spring Batch?

I was wondering for a flow like this:

ItemReader -> ItemProcessor -> ItemWriter 

where each one of those is a custom class implementing the equivalent interface and in a chunk-oriented step, When each constructor will be called?

As I understand so far(correct me if I'm wrong) the ItemWriter constructor will be called once in the beginning of the step and for each chunk, write() will be called only. This rule applies for the other 2?

Vinay answer is correct but need some elaboration.

For reader-processor->writer Spring calls the default constructor (let's ignore @PostConstruct etc.) Scope(“step”), as the name implies is creating a new bean for every step. Step does not have to be one to one with thread, for example let's say I have the following reader-processor->writer

  @Component
  @Scope("step")
  public class DoNothingItemReader  implements ItemReader<String>{
            public DoNothingItemReader() {
                LOGGER.info(String.format("New %s created" 
                ,ClassUtils.getShortName(this.getClass())));
            }

            @Override
            public String read() throws Exception{
                LOGGER.info("Nothing to read...");
            ..
            }

        } 

    @Component
    @Scope("step")
    public class DoNothingItemProcessor implements ItemProcessor<String, String> {
        public DoNothingItemProcessor() {
            LOGGER.info(String.format("New %s created"
                    ,ClassUtils.getShortName(this.getClass())));
        }

        @Override
        public String process(String i) throws Exception {
            LOGGER.info("Nothing to process...");
            return i;
        }

    }

    @Component
    @Scope("step")
    public class DoNothingItemWritter implements ItemWriter<String[]> {
        public DoNothingItemWritter() {
            LOGGER.info(String.format("New %s created" 
                    ,ClassUtils.getShortName(this.getClass())));
        }

        @Override
        public void write(List<? extends String[]> items) throws Exception {
            LOGGER.info("Nothing to write...");

        }

Now we reuse this above in two steps eg

    <batch:job id="testScopStep">
            <batch:step id="step1" next="step2">
                <batch:tasklet transaction-manager="transactionManager">
                    <batch:chunk reader="doNothingItemReader"
processor="doNothingItemProcessor"
                        writer="doNothingItemWritter" commit-interval="3">
                    </batch:chunk>
                </batch:tasklet>
            </batch:step>
             <batch:step id="step2">
                <batch:tasklet transaction-manager="transactionManager">
                    <batch:chunk reader="doNothingItemReader"
processor="doNothingItemProcessor"
                        writer="doNothingItemWritter" commit-interval="3">
                    </batch:chunk>
                </batch:tasklet>
            </batch:step>
            </batch:job>

The constructor will be called twice for ever reader->processor->writer
The log will be

 [SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] launched>
 [SimpleStepHandler] - <Executing step: [step1]>
 [DoNothingItemReader] - <New DoNothingItemReader created>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemProcessor] - <New DoNothingItemProcessor created>
 [DoNothingItemProcessor] - <Nothing to process...>
 [DoNothingItemProcessor] - <Nothing to process...>
 [DoNothingItemWritter] - <New DoNothingItemWritter created>
 [DoNothingItemWritter] - <Nothing to write...>
 [SimpleStepHandler] - <Executing step: [step2]>
 [DoNothingItemReader] - <New DoNothingItemReader created>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemProcessor] - <New DoNothingItemProcessor created>
 [DoNothingItemProcessor] - <Nothing to process...>
 [DoNothingItemProcessor] - <Nothing to process...>
 [DoNothingItemWritter] - <New DoNothingItemWritter created>
 [DoNothingItemWritter] - <Nothing to write...>
 [SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] completed 

Now consider the following scenario when we are using a composite writer

 <batch:job id="testScopStep">
<batch:step id="step1">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk reader="doNothingItemReader" 
                    processor="doNothingItemProcessor"
                    writer="compositeWriter" commit-interval="3">
                </batch:chunk>
            </batch:tasklet>
        </batch:step> 
</batch:job>

Here The constructors will be called only once.
The log will display

[SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] launched>
 [SimpleStepHandler] - <Executing step: [step1]>
 [DoNothingItemReader] - <New DoNothingItemReader created>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemReader] - <Nothing to read...>
 [DoNothingItemProcessor] - <New DoNothingItemProcessor created>
 [DoNothingItemProcessor] - <Nothing to process...>
 [DoNothingItemProcessor] - <Nothing to process...>
 [DoNothingItemWritter] - <New DoNothingItemWritter created>
 [DoNothingItemWritter] - <Nothing to write...> 
 [DoNothingItemWritter] - <Nothing to write...>
 [SimpleJobLauncher] - <Job: [FlowJob: [name=testScopStep]] completed

So in such case we should be careful taking in to consideration we are sharing the same writer.

ItemWriter, Reader and Writer are all Spring beans. If you have marked them with @component then all of them created once only and constructor is called when you create ApplicationContext. Though there are different scope you can specify like @scope("step") . This will make each thread will have their own component in Multi-threaded batch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM